Profile fragment
This commit is contained in:
parent
9b749202fd
commit
629ed62e03
29 changed files with 1733 additions and 9 deletions
|
@ -37,7 +37,7 @@
|
||||||
<ConfirmationsSetting value="0" id="Add" />
|
<ConfirmationsSetting value="0" id="Add" />
|
||||||
<ConfirmationsSetting value="0" id="Remove" />
|
<ConfirmationsSetting value="0" id="Remove" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|
|
@ -24,5 +24,11 @@ dependencies {
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
compile 'com.android.support:appcompat-v7:23.4.0'
|
compile 'com.android.support:appcompat-v7:23.4.0'
|
||||||
compile 'com.android.support:support-v4:23.4.0'
|
compile 'com.android.support:support-v4:23.4.0'
|
||||||
compile 'com.android.support:cardview-v7:23.0.+'
|
compile 'com.android.support:cardview-v7:23.4.0'
|
||||||
compile 'com.android.support:recyclerview-v7:23.0.+'}
|
compile 'com.android.support:recyclerview-v7:23.4.0'
|
||||||
|
compile 'com.squareup:otto:1.3.7'
|
||||||
|
compile 'com.j256.ormlite:ormlite-core:4.46'
|
||||||
|
compile 'com.j256.ormlite:ormlite-android:4.46'
|
||||||
|
compile 'com.github.tony19:logback-android-classic:1.1.1-4'
|
||||||
|
compile 'org.slf4j:slf4j-api:1.7.12'
|
||||||
|
}
|
||||||
|
|
|
@ -2,19 +2,51 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="info.nightscout.androidaps">
|
package="info.nightscout.androidaps">
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
|
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
android:name=".MainApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
|
android:process=":mainProcess"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<!-- Receiver from NSClient -->
|
||||||
|
<receiver
|
||||||
|
android:name="info.nightscout.client.receivers.NSClientDataReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="true"
|
||||||
|
android:process=":mainProcess">
|
||||||
|
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="info.nightscout.client.NEW_TREATMENT" />
|
||||||
|
<action android:name="info.nightscout.client.CHANGED_TREATMENT" />
|
||||||
|
<action android:name="info.nightscout.client.REMOVED_TREATMENT" />
|
||||||
|
<action android:name="info.nightscout.client.NEW_PROFILE" />
|
||||||
|
<action android:name="info.nightscout.client.NEW_SGV" />
|
||||||
|
<action android:name="info.nightscout.client.NEW_STATUS" />
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
35
app/src/main/assets/logback.xml
Normal file
35
app/src/main/assets/logback.xml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<configuration>
|
||||||
|
<!-- Create a file appender for a log in the application's data directory -->
|
||||||
|
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||||
|
<file>/storage/sdcard0/AndroidAPS/AndroidAPS.log</file>
|
||||||
|
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||||
|
<!-- daily rollover. Make sure the path matches the one in the file element or else
|
||||||
|
the rollover logs are placed in the working directory. -->
|
||||||
|
<fileNamePattern>/storage/sdcard0/AndroidAPS/AndroidAPS._%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||||
|
|
||||||
|
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||||
|
<maxFileSize>5MB</maxFileSize>
|
||||||
|
</timeBasedFileNamingAndTriggeringPolicy>
|
||||||
|
<!-- keep 30 days' worth of history -->
|
||||||
|
<maxHistory>120</maxHistory>
|
||||||
|
</rollingPolicy>
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<appender name="logcat" class="ch.qos.logback.classic.android.LogcatAppender">
|
||||||
|
<tagEncoder>
|
||||||
|
<pattern>%logger{0}</pattern>
|
||||||
|
</tagEncoder>
|
||||||
|
<encoder>
|
||||||
|
<pattern>[%thread] %-5level %logger{36} - %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<!-- Write INFO (and higher-level) messages to the log file -->
|
||||||
|
<root level="DEBUG">
|
||||||
|
<appender-ref ref="file" />
|
||||||
|
<appender-ref ref="logcat" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
|
@ -1,5 +1,7 @@
|
||||||
package info.nightscout.androidaps;
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
@ -7,11 +9,19 @@ import android.support.v7.widget.Toolbar;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.ProfileViewer.ProfileViewerFragment;
|
||||||
import info.nightscout.androidaps.tabs.*;
|
import info.nightscout.androidaps.tabs.*;
|
||||||
import info.nightscout.androidaps.plugins.Objectives.ObjectivesFragment;
|
import info.nightscout.androidaps.plugins.Objectives.ObjectivesFragment;
|
||||||
import info.nightscout.androidaps.plugins.Test.TestFragment;
|
import info.nightscout.androidaps.plugins.Test.TestFragment;
|
||||||
|
import info.nightscout.client.broadcasts.Intents;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity implements ObjectivesFragment.OnFragmentInteractionListener {
|
public class MainActivity extends AppCompatActivity implements ObjectivesFragment.OnFragmentInteractionListener {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(MainActivity.class);
|
||||||
|
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private SlidingTabLayout mTabs;
|
private SlidingTabLayout mTabs;
|
||||||
|
@ -26,6 +36,7 @@ public class MainActivity extends AppCompatActivity implements ObjectivesFragmen
|
||||||
// Register all tabs in app here
|
// Register all tabs in app here
|
||||||
mAdapter = new TabPageAdapter(getSupportFragmentManager());
|
mAdapter = new TabPageAdapter(getSupportFragmentManager());
|
||||||
mAdapter.registerNewFragment("Test", TestFragment.newInstance());
|
mAdapter.registerNewFragment("Test", TestFragment.newInstance());
|
||||||
|
mAdapter.registerNewFragment("Profile", ProfileViewerFragment.newInstance());
|
||||||
mAdapter.registerNewFragment("Objectives", ObjectivesFragment.newInstance());
|
mAdapter.registerNewFragment("Objectives", ObjectivesFragment.newInstance());
|
||||||
|
|
||||||
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||||
|
@ -34,7 +45,11 @@ public class MainActivity extends AppCompatActivity implements ObjectivesFragmen
|
||||||
mPager.setAdapter(mAdapter);
|
mPager.setAdapter(mAdapter);
|
||||||
mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
|
||||||
mTabs.setViewPager(mPager);
|
mTabs.setViewPager(mPager);
|
||||||
|
|
||||||
|
registerBus();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||||
|
@ -53,4 +68,15 @@ public class MainActivity extends AppCompatActivity implements ObjectivesFragmen
|
||||||
public void onFragmentInteraction(String param) {
|
public void onFragmentInteraction(String param) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerBus() {
|
||||||
|
try {
|
||||||
|
MainApp.bus().unregister(this);
|
||||||
|
} catch (RuntimeException x) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
MainApp.bus().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
109
app/src/main/java/info/nightscout/androidaps/MainApp.java
Normal file
109
app/src/main/java/info/nightscout/androidaps/MainApp.java
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
package info.nightscout.androidaps;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||||
|
import com.squareup.otto.Bus;
|
||||||
|
import com.squareup.otto.ThreadEnforcer;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.data.Pump;
|
||||||
|
import info.nightscout.client.data.NSProfile;
|
||||||
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
|
|
||||||
|
|
||||||
|
public class MainApp extends Application {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(MainApp.class);
|
||||||
|
|
||||||
|
public static final String PREFS_NAME = "NightscoutProfile";
|
||||||
|
|
||||||
|
|
||||||
|
private static Bus sBus;
|
||||||
|
private static MainApp sInstance;
|
||||||
|
|
||||||
|
private static NSProfile nsProfile = null;
|
||||||
|
private static String activeProfile = null;
|
||||||
|
|
||||||
|
private static Pump activePump = null;
|
||||||
|
|
||||||
|
private static DatabaseHelper databaseHelper = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
|
||||||
|
sBus = new Bus(ThreadEnforcer.ANY);
|
||||||
|
sInstance = this;
|
||||||
|
|
||||||
|
log.debug("Loading stored profile");
|
||||||
|
SharedPreferences store = getSharedPreferences(PREFS_NAME, 0);
|
||||||
|
activeProfile = store.getString("activeProfile", null);
|
||||||
|
String profileString = store.getString("profile", null);
|
||||||
|
if (profileString != null) {
|
||||||
|
try {
|
||||||
|
log.debug("Loaded profile: " + profileString);
|
||||||
|
log.debug("Loaded active profile: " + activeProfile);
|
||||||
|
setNSProfile(new NSProfile(new JSONObject(profileString), activeProfile));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
log.debug("Stored profile not found");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bus bus() {
|
||||||
|
return sBus;
|
||||||
|
}
|
||||||
|
public static MainApp instance() {
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DatabaseHelper getDbHelper() {
|
||||||
|
if (databaseHelper == null) {
|
||||||
|
databaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
|
||||||
|
}
|
||||||
|
return databaseHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void closeDbHelper() {
|
||||||
|
if (databaseHelper != null) {
|
||||||
|
databaseHelper.close();
|
||||||
|
databaseHelper = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTerminate() {
|
||||||
|
super.onTerminate();
|
||||||
|
databaseHelper.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NSProfile getNSProfile() {
|
||||||
|
return nsProfile;
|
||||||
|
}
|
||||||
|
public static void setNSProfile(NSProfile profile) {
|
||||||
|
nsProfile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getActiveProfile() {
|
||||||
|
return activeProfile;
|
||||||
|
}
|
||||||
|
public static void setActiveProfile(String activeprofile) {
|
||||||
|
activeProfile = activeprofile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pump getActivePump() {
|
||||||
|
return activePump;
|
||||||
|
}
|
||||||
|
public static void setActivePump(Pump activepump) {
|
||||||
|
activePump = activepump;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
10
app/src/main/java/info/nightscout/androidaps/data/Pump.java
Normal file
10
app/src/main/java/info/nightscout/androidaps/data/Pump.java
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
package info.nightscout.androidaps.data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 04.06.2016.
|
||||||
|
*/
|
||||||
|
public abstract class Pump {
|
||||||
|
|
||||||
|
// Upload to pump new basal profile from MainApp.getNSProfile()
|
||||||
|
public abstract void setNewBasalProfile();
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
|
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||||
|
import com.j256.ormlite.dao.Dao;
|
||||||
|
import com.j256.ormlite.stmt.QueryBuilder;
|
||||||
|
import com.j256.ormlite.support.ConnectionSource;
|
||||||
|
import com.j256.ormlite.table.TableUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(DatabaseHelper.class);
|
||||||
|
|
||||||
|
public static final String DATABASE_NAME = "AndroidAPSDb";
|
||||||
|
|
||||||
|
private static final int DATABASE_VERSION = 1;
|
||||||
|
|
||||||
|
public DatabaseHelper(Context context) {
|
||||||
|
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) {
|
||||||
|
try {
|
||||||
|
log.info("onCreate");
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, TempBasal.class);
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||||
|
// TODO: add bg support
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(DatabaseHelper.class.getName(), "Can't create database", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion) {
|
||||||
|
try {
|
||||||
|
log.info(DatabaseHelper.class.getName(), "onUpgrade");
|
||||||
|
TableUtils.dropTable(connectionSource, TempBasal.class, true);
|
||||||
|
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||||
|
onCreate(database, connectionSource);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error(DatabaseHelper.class.getName(), "Can't drop databases", e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the database connections and clear any cached DAOs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetDatabases() {
|
||||||
|
try {
|
||||||
|
TableUtils.dropTable(connectionSource, TempBasal.class, true);
|
||||||
|
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, TempBasal.class);
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetTreatments() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||||
|
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dao<TempBasal, Long> getDaoTempBasals() throws SQLException {
|
||||||
|
return getDao(TempBasal.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dao<Treatment, Long> getDaoTreatments() throws SQLException {
|
||||||
|
return getDao(Treatment.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
132
app/src/main/java/info/nightscout/androidaps/db/TempBasal.java
Normal file
132
app/src/main/java/info/nightscout/androidaps/db/TempBasal.java
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
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.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = "TempBasals")
|
||||||
|
public class TempBasal {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(TempBasal.class);
|
||||||
|
|
||||||
|
public long getTimeIndex() {
|
||||||
|
return (long) Math.ceil(timeStart.getTime() / 60000d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeIndex(long timeIndex) {
|
||||||
|
this.timeIndex = timeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DatabaseField(id = true, useGetSet = true)
|
||||||
|
public long timeIndex;
|
||||||
|
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public Date timeStart;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public Date timeEnd;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public int percent; // In % of current basal
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public int absolute; // Absolute value in U
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public int duration; // in minutes
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public boolean isExtended; // true if set as extended bolus
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public boolean isAbsolute; // true if if set as absolute value in U
|
||||||
|
|
||||||
|
/*
|
||||||
|
public Iob calcIob() {
|
||||||
|
Iob iob = new Iob();
|
||||||
|
|
||||||
|
long msAgo = getMillisecondsFromStart();
|
||||||
|
Calendar startAdjusted = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
|
startAdjusted.setTime(this.timeStart);
|
||||||
|
int minutes = startAdjusted.get(Calendar.MINUTE);
|
||||||
|
minutes = minutes % 4;
|
||||||
|
if (startAdjusted.get(Calendar.SECOND) > 0 && minutes == 0) {
|
||||||
|
minutes += 4;
|
||||||
|
}
|
||||||
|
startAdjusted.add(Calendar.MINUTE, minutes);
|
||||||
|
startAdjusted.set(Calendar.SECOND, 0);
|
||||||
|
|
||||||
|
IobCalc iobCalc = new IobCalc();
|
||||||
|
iobCalc.setTime(new Date());
|
||||||
|
iobCalc.setAmount(-1.0d * (baseRatio - tempRatio) / 15.0d / 100.0d);
|
||||||
|
|
||||||
|
long timeStartTime = startAdjusted.getTimeInMillis();
|
||||||
|
Date currentTimeEnd = timeEnd;
|
||||||
|
if (currentTimeEnd == null) {
|
||||||
|
currentTimeEnd = new Date();
|
||||||
|
if (getPlannedTimeEnd().getTime() < currentTimeEnd.getTime()) {
|
||||||
|
currentTimeEnd = getPlannedTimeEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (long time = timeStartTime; time < currentTimeEnd.getTime(); time += 4 * 60_000) {
|
||||||
|
Date start = new Date(time);
|
||||||
|
|
||||||
|
iobCalc.setTimeStart(start);
|
||||||
|
iob.plus(iobCalc.invoke());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Settings.logTempIOBCalculation) {
|
||||||
|
log.debug("TempIOB start: " + this.timeStart + " end: " + this.timeEnd + " Percent: " + this.percent + " Duration: " + this.duration + " CalcDurat: " + (int) ((currentTimeEnd.getTime() - this.timeStart.getTime()) / 1000 / 60)
|
||||||
|
+ "min minAgo: " + (int) (msAgo / 1000 / 60) + " IOB: " + iob.iobContrib + " Activity: " + iob.activityContrib + " Impact: " + (-0.01d * (baseRatio - tempRatio) * ((currentTimeEnd.getTime() - this.timeStart.getTime()) / 1000 / 60) / 60)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return iob;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
// Determine end of basal
|
||||||
|
public Date getTimeEnd() {
|
||||||
|
Date tempBasalTimePlannedEnd = getPlannedTimeEnd();
|
||||||
|
|
||||||
|
// End already exists in database
|
||||||
|
if (timeEnd != null) {
|
||||||
|
return timeEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not return planned time
|
||||||
|
return tempBasalTimePlannedEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getPlannedTimeEnd() {
|
||||||
|
return new Date(timeStart.getTime() + 60 * 1_000 * duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getMillisecondsFromStart() {
|
||||||
|
return new Date().getTime() - timeStart.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemainingMinutes() {
|
||||||
|
long remainingMin = (getTimeEnd().getTime() - new Date().getTime()) / 1000 / 60;
|
||||||
|
return (remainingMin < 0) ? 0 : (int) remainingMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "TempBasal{" +
|
||||||
|
"timeIndex=" + timeIndex +
|
||||||
|
", timeStart=" + timeStart +
|
||||||
|
", timeEnd=" + timeEnd +
|
||||||
|
", percent=" + percent +
|
||||||
|
", absolute=" + absolute +
|
||||||
|
", duration=" + duration +
|
||||||
|
", isAbsolute=" + isAbsolute +
|
||||||
|
", isExtended=" + isExtended +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
173
app/src/main/java/info/nightscout/androidaps/db/Treatment.java
Normal file
173
app/src/main/java/info/nightscout/androidaps/db/Treatment.java
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.j256.ormlite.field.DatabaseField;
|
||||||
|
import com.j256.ormlite.table.DatabaseTable;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.client.broadcasts.Intents;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.utils.DateUtil;
|
||||||
|
|
||||||
|
@DatabaseTable(tableName = "Treatments")
|
||||||
|
public class Treatment {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(Treatment.class);
|
||||||
|
|
||||||
|
public long getTimeIndex() {
|
||||||
|
return (long) Math.ceil(created_at.getTime() / 60000d);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeIndex(long timeIndex) {
|
||||||
|
this.timeIndex = timeIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@DatabaseField(id = true, useGetSet = true)
|
||||||
|
public long timeIndex;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public String _id;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public Date created_at;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public Double insulin;
|
||||||
|
|
||||||
|
@DatabaseField
|
||||||
|
public Double carbs;
|
||||||
|
|
||||||
|
public void copyFrom(Treatment t) {
|
||||||
|
this._id = t._id;
|
||||||
|
this.created_at = t.created_at;
|
||||||
|
this.insulin = t.insulin;
|
||||||
|
this.carbs = t.carbs;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
public Iob iobCalc(Date time, Double dia) {
|
||||||
|
Double diaratio = 3.0 / dia;
|
||||||
|
Double peak = 75d;
|
||||||
|
Double end = 180d;
|
||||||
|
//var sens = profile_data.sens;
|
||||||
|
|
||||||
|
Iob results = new Iob();
|
||||||
|
|
||||||
|
if (insulin != 0) {
|
||||||
|
long bolusTime = created_at.getTime();
|
||||||
|
Double minAgo = diaratio * (time.getTime() - bolusTime) / 1000 / 60;
|
||||||
|
Double iobContrib = 0d;
|
||||||
|
Double activityContrib = 0d;
|
||||||
|
|
||||||
|
if (minAgo < peak) {
|
||||||
|
Double x = (minAgo/5 + 1);
|
||||||
|
iobContrib = insulin * (1 - 0.001852 * x * x + 0.001852 * x);
|
||||||
|
//activityContrib=sens*treatment.insulin*(2/dia/60/peak)*minAgo;
|
||||||
|
activityContrib = insulin * (2 / dia / 60 / peak) * minAgo;
|
||||||
|
} else if (minAgo < end) {
|
||||||
|
Double y = (minAgo-peak)/5;
|
||||||
|
iobContrib = insulin * (0.001323 * y * y - .054233 * y + .55556);
|
||||||
|
//activityContrib=sens*treatment.insulin*(2/dia/60-(minAgo-peak)*2/dia/60/(60*dia-peak));
|
||||||
|
activityContrib = insulin * (2 / dia / 60 - (minAgo - peak) * 2 / dia / 60 / (60 * dia - peak));
|
||||||
|
}
|
||||||
|
|
||||||
|
results.iobContrib = iobContrib;
|
||||||
|
results.activityContrib = activityContrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iob calcIobOpenAPS() {
|
||||||
|
IobCalc calc = new IobCalc(created_at,insulin,new Date());
|
||||||
|
calc.setBolusDiaTimesTwo();
|
||||||
|
Iob iob = calc.invoke();
|
||||||
|
|
||||||
|
return iob;
|
||||||
|
}
|
||||||
|
public Iob calcIob() {
|
||||||
|
IobCalc calc = new IobCalc(created_at,insulin,new Date());
|
||||||
|
Iob iob = calc.invoke();
|
||||||
|
|
||||||
|
return iob;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public long getMillisecondsFromStart() {
|
||||||
|
return new Date().getTime() - created_at.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String log() {
|
||||||
|
return "Treatment{" +
|
||||||
|
"timeIndex: " + timeIndex +
|
||||||
|
", _id: " + _id +
|
||||||
|
", insulin: " + insulin +
|
||||||
|
", carbs: " + carbs +
|
||||||
|
", created_at: " +
|
||||||
|
"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendToNSClient() {
|
||||||
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("action", "dbAdd");
|
||||||
|
bundle.putString("collection", "treatments");
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
try {
|
||||||
|
data.put("eventType", "Meal Bolus");
|
||||||
|
if (insulin != 0d) data.put("insulin", insulin);
|
||||||
|
if (carbs != 0d) data.put("carbs", carbs.intValue());
|
||||||
|
data.put("created_at", DateUtil.toISOString(created_at));
|
||||||
|
data.put("timeIndex", timeIndex);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
bundle.putString("data", data.toString());
|
||||||
|
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
||||||
|
intent.putExtras(bundle);
|
||||||
|
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
List<ResolveInfo> q = context.getPackageManager().queryBroadcastReceivers(intent, 0);
|
||||||
|
if (q.size() < 1) {
|
||||||
|
log.error("DBADD No receivers");
|
||||||
|
} else log.debug("DBADD dbAdd " + q.size() + " receivers " + data.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateToNSClient() {
|
||||||
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString("action", "dbUpdate");
|
||||||
|
bundle.putString("collection", "treatments");
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
try {
|
||||||
|
data.put("eventType", "Meal Bolus");
|
||||||
|
data.put("insulin", insulin);
|
||||||
|
data.put("carbs", carbs.intValue());
|
||||||
|
data.put("created_at", DateUtil.toISOString(created_at));
|
||||||
|
data.put("timeIndex", timeIndex);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
bundle.putString("data", data.toString());
|
||||||
|
bundle.putString("_id", _id);
|
||||||
|
Intent intent = new Intent(Intents.ACTION_DATABASE);
|
||||||
|
intent.putExtras(bundle);
|
||||||
|
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
|
||||||
|
context.sendBroadcast(intent);
|
||||||
|
List<ResolveInfo> q = context.getPackageManager().queryBroadcastReceivers(intent, 0);
|
||||||
|
if (q.size() < 1) {
|
||||||
|
log.error("DBUPDATE No receivers");
|
||||||
|
} else log.debug("DBUPDATE dbUpdate " + q.size() + " receivers " + _id + " " + data.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 04.06.2016.
|
||||||
|
*/
|
||||||
|
public class EventNewBasalProfile {
|
||||||
|
// TODO: implement proper GUI update
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package info.nightscout.androidaps.events;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 04.06.2016.
|
||||||
|
*/
|
||||||
|
public class EventTreatmentChange {
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ import android.widget.TextView;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
|
||||||
|
@ -139,7 +138,7 @@ public class ObjectivesFragment extends Fragment {
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
View view = inflater.inflate(R.layout.fragment_objectives, container, false);
|
View view = inflater.inflate(R.layout.objectives_fragment, container, false);
|
||||||
|
|
||||||
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
|
recyclerView = (RecyclerView) view.findViewById(R.id.objectives_recyclerview);
|
||||||
recyclerView.setHasFixedSize(true);
|
recyclerView.setHasFixedSize(true);
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package info.nightscout.androidaps.plugins.ProfileViewer;
|
||||||
|
|
||||||
|
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.TextView;
|
||||||
|
|
||||||
|
import com.squareup.otto.Subscribe;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||||
|
import info.nightscout.client.data.NSProfile;
|
||||||
|
|
||||||
|
public class ProfileViewerFragment extends Fragment {
|
||||||
|
private static TextView noProfile;
|
||||||
|
private static TextView dia;
|
||||||
|
private static TextView activeProfile;
|
||||||
|
private static TextView ic;
|
||||||
|
private static TextView isf;
|
||||||
|
private static TextView basal;
|
||||||
|
private static TextView target;
|
||||||
|
|
||||||
|
private static DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||||
|
|
||||||
|
public ProfileViewerFragment() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProfileViewerFragment newInstance(String param1, String param2) {
|
||||||
|
ProfileViewerFragment fragment = new ProfileViewerFragment();
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
registerBus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
View layout = inflater.inflate(R.layout.profileviewer_fragment, container, false);
|
||||||
|
|
||||||
|
noProfile = (TextView) layout.findViewById(R.id.profileview_noprofile);
|
||||||
|
dia = (TextView) layout.findViewById(R.id.profileview_dia);
|
||||||
|
activeProfile = (TextView) layout.findViewById(R.id.profileview_activeprofile);
|
||||||
|
ic = (TextView) layout.findViewById(R.id.profileview_ic);
|
||||||
|
isf = (TextView) layout.findViewById(R.id.profileview_isf);
|
||||||
|
basal = (TextView) layout.findViewById(R.id.profileview_basal);
|
||||||
|
target = (TextView) layout.findViewById(R.id.profileview_target);
|
||||||
|
|
||||||
|
setContent();
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ProfileViewerFragment newInstance() {
|
||||||
|
ProfileViewerFragment fragment = new ProfileViewerFragment();
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setContent() {
|
||||||
|
NSProfile profile = MainApp.getNSProfile();
|
||||||
|
if (profile == null) {
|
||||||
|
noProfile.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
noProfile.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
dia.setText(formatNumber2decimalplaces.format(profile.getDia()) + " h");
|
||||||
|
activeProfile.setText(profile.getActiveProfile());
|
||||||
|
ic.setText(profile.getIcList());
|
||||||
|
isf.setText(profile.getIsfList());
|
||||||
|
basal.setText(profile.getBasalList());
|
||||||
|
target.setText(profile.getTargetList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerBus() {
|
||||||
|
try {
|
||||||
|
MainApp.bus().unregister(this);
|
||||||
|
} catch (RuntimeException x) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
MainApp.bus().register(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void onStatusEvent(final EventNewBasalProfile ev) {
|
||||||
|
setContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -30,7 +30,7 @@ public class TestFragment extends Fragment {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstance) {
|
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstance) {
|
||||||
View layout = inflater.inflate(R.layout.app_fragment, container, false);
|
View layout = inflater.inflate(R.layout.test_fragment, container, false);
|
||||||
textView = (TextView) layout.findViewById(R.id.position);
|
textView = (TextView) layout.findViewById(R.id.position);
|
||||||
Bundle bundle = getArguments();
|
Bundle bundle = getArguments();
|
||||||
if (bundle != null) {
|
if (bundle != null) {
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package info.nightscout.client.broadcasts;
|
||||||
|
|
||||||
|
public interface Intents {
|
||||||
|
// NSClient -> App
|
||||||
|
String ACTION_NEW_TREATMENT = "info.nightscout.client.NEW_TREATMENT";
|
||||||
|
String ACTION_CHANGED_TREATMENT = "info.nightscout.client.CHANGED_TREATMENT";
|
||||||
|
String ACTION_REMOVED_TREATMENT = "info.nightscout.client.REMOVED_TREATMENT";
|
||||||
|
String ACTION_NEW_PROFILE = "info.nightscout.client.NEW_PROFILE";
|
||||||
|
String ACTION_NEW_SGV = "info.nightscout.client.NEW_SGV";
|
||||||
|
String ACTION_NEW_STATUS = "info.nightscout.client.NEW_STATUS";
|
||||||
|
|
||||||
|
|
||||||
|
// App -> NSClient
|
||||||
|
String ACTION_DATABASE = "info.nightscout.client.DBACCESS";
|
||||||
|
}
|
22
app/src/main/java/info/nightscout/client/data/NSCal.java
Normal file
22
app/src/main/java/info/nightscout/client/data/NSCal.java
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
package info.nightscout.client.data;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
public class NSCal {
|
||||||
|
public long date;
|
||||||
|
public double slope;
|
||||||
|
public double intercept;
|
||||||
|
public double scale = 1;
|
||||||
|
|
||||||
|
public void set(JSONObject json) {
|
||||||
|
try {
|
||||||
|
date = json.getLong("date");
|
||||||
|
slope = json.getDouble("slope");
|
||||||
|
intercept = json.getDouble("intercept");
|
||||||
|
scale = json.getDouble("scale");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
282
app/src/main/java/info/nightscout/client/data/NSProfile.java
Normal file
282
app/src/main/java/info/nightscout/client/data/NSProfile.java
Normal file
|
@ -0,0 +1,282 @@
|
||||||
|
package info.nightscout.client.data;
|
||||||
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
public class NSProfile {
|
||||||
|
private JSONObject json = null;
|
||||||
|
private String activeProfile = null;
|
||||||
|
|
||||||
|
public NSProfile(JSONObject json, String activeProfile) {
|
||||||
|
this.json = json;
|
||||||
|
this.activeProfile = activeProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONObject getDefaultProfile() {
|
||||||
|
String defaultProfileName = null;
|
||||||
|
JSONObject store;
|
||||||
|
JSONObject profile = null;
|
||||||
|
try {
|
||||||
|
defaultProfileName = (String) json.get("defaultProfile");
|
||||||
|
store = json.getJSONObject("store");
|
||||||
|
if (activeProfile != null && store.has(activeProfile)) {
|
||||||
|
defaultProfileName = activeProfile;
|
||||||
|
}
|
||||||
|
profile = store.getJSONObject(defaultProfileName);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String log() {
|
||||||
|
String ret = "\n";
|
||||||
|
for (Integer hour = 0; hour < 24; hour ++) {
|
||||||
|
double value = getBasal(hour * 60 * 60);
|
||||||
|
ret += "NS basal value for " + hour + ":00 is " + value + "\n";
|
||||||
|
}
|
||||||
|
ret += "NS units: " + getUnits();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject getData () {
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getDia() {
|
||||||
|
Double dia;
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
dia = profile.getDouble("dia");
|
||||||
|
return dia;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 3D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getCarbAbsorbtionRate() {
|
||||||
|
Double carbAbsorptionRate;
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
carbAbsorptionRate = profile.getDouble("carbs_hr");
|
||||||
|
return carbAbsorptionRate;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mmol or mg/dl
|
||||||
|
public String getUnits() {
|
||||||
|
String units;
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
units = profile.getString("units");
|
||||||
|
return units;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "mg/dl";
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimeZone getTimeZone() {
|
||||||
|
TimeZone timeZone;
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return TimeZone.getTimeZone(profile.getString("timezone"));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TimeZone.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getValueToTime(JSONArray array, Integer timeAsSeconds) {
|
||||||
|
Double lastValue = null;
|
||||||
|
|
||||||
|
for(Integer index = 0; index < array.length(); index++) {
|
||||||
|
try {
|
||||||
|
JSONObject o = array.getJSONObject(index);
|
||||||
|
Integer tas = o.getInt("timeAsSeconds");
|
||||||
|
Double value = o.getDouble("value");
|
||||||
|
if (lastValue == null) lastValue = value;
|
||||||
|
if (timeAsSeconds < tas) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lastValue = value;
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValuesList(JSONArray array, JSONArray 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");
|
||||||
|
retValue += " ";
|
||||||
|
retValue += format.format(o.getDouble("value"));
|
||||||
|
if (array2 != null) {
|
||||||
|
JSONObject o2 = array2.getJSONObject(index);
|
||||||
|
retValue += " - ";
|
||||||
|
retValue += format.format(o2.getDouble("value"));
|
||||||
|
}
|
||||||
|
retValue += " " + units;
|
||||||
|
retValue += "\n";
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getIsf(Integer timeAsSeconds) {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValueToTime(profile.getJSONArray("sens"),timeAsSeconds);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIsfList() {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValuesList(profile.getJSONArray("sens"), null, new DecimalFormat("0"), getUnits() + "/U");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getIc(Integer timeAsSeconds) {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValueToTime(profile.getJSONArray("carbratio"),timeAsSeconds);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIcList() {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValuesList(profile.getJSONArray("carbratio"), null, new DecimalFormat("0"), "g");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getBasal(Integer timeAsSeconds) {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValueToTime(profile.getJSONArray("basal"),timeAsSeconds);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBasalList() {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValuesList(profile.getJSONArray("basal"), null, new DecimalFormat("0.00"), "U");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTargetLow(Integer timeAsSeconds) {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValueToTime(profile.getJSONArray("target_low"),timeAsSeconds);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getTargetHigh(Integer timeAsSeconds) {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValueToTime(profile.getJSONArray("target_high"), timeAsSeconds);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0D;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTargetList() {
|
||||||
|
JSONObject profile = getDefaultProfile();
|
||||||
|
if (profile != null) {
|
||||||
|
try {
|
||||||
|
return getValuesList(profile.getJSONArray("target_low"),profile.getJSONArray("target_high"), new DecimalFormat("0.0"), getUnits());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getActiveProfile() {
|
||||||
|
return activeProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Double getMaxDailyBasal() {
|
||||||
|
Double max = 0d;
|
||||||
|
for (Integer hour = 0; hour < 24; hour ++) {
|
||||||
|
double value = getBasal(hour * 60 * 60);
|
||||||
|
if (value > max) max = value;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int secondsFromMidnight() {
|
||||||
|
Calendar c = Calendar.getInstance();
|
||||||
|
long now = c.getTimeInMillis();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
63
app/src/main/java/info/nightscout/client/data/NSSgv.java
Normal file
63
app/src/main/java/info/nightscout/client/data/NSSgv.java
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package info.nightscout.client.data;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* {"mgdl":105,"mills":1455136282375,"device":"xDrip-BluetoothWixel","direction":"Flat","filtered":98272,"unfiltered":98272,"noise":1,"rssi":100}
|
||||||
|
*/
|
||||||
|
public class NSSgv {
|
||||||
|
private JSONObject data;
|
||||||
|
|
||||||
|
public NSSgv(JSONObject obj) {
|
||||||
|
this.data = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringOrNull(String key) {
|
||||||
|
String ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getString(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Integer getIntegerOrNull(String key) {
|
||||||
|
Integer ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getInt(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Long getLongOrNull(String key) {
|
||||||
|
Long ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getLong(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
public JSONObject getData () { return data; }
|
||||||
|
public Integer getMgdl () { return getIntegerOrNull("mgdl"); }
|
||||||
|
public Integer getFiltered () { return getIntegerOrNull("filtered"); }
|
||||||
|
public Integer getUnfiltered () { return getIntegerOrNull("unfiltered"); }
|
||||||
|
public Integer getNoise () { return getIntegerOrNull("noise"); }
|
||||||
|
public Integer getRssi () { return getIntegerOrNull("rssi"); }
|
||||||
|
public Long getMills () { return getLongOrNull("mills"); }
|
||||||
|
public String getDevice () { return getStringOrNull("device"); }
|
||||||
|
public String getDirection () { return getStringOrNull("direction"); }
|
||||||
|
|
||||||
|
}
|
105
app/src/main/java/info/nightscout/client/data/NSStatus.java
Normal file
105
app/src/main/java/info/nightscout/client/data/NSStatus.java
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
package info.nightscout.client.data;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
{
|
||||||
|
status: 'ok'
|
||||||
|
, name: env.name
|
||||||
|
, version: env.version
|
||||||
|
, versionNum: versionNum (for ver 1.2.3 contains 10203)
|
||||||
|
, serverTime: new Date().toISOString()
|
||||||
|
, apiEnabled: apiEnabled
|
||||||
|
, careportalEnabled: apiEnabled && env.settings.enable.indexOf('careportal') > -1
|
||||||
|
, boluscalcEnabled: apiEnabled && env.settings.enable.indexOf('boluscalc') > -1
|
||||||
|
, head: env.head
|
||||||
|
, settings: env.settings
|
||||||
|
, extendedSettings: ctx.plugins && ctx.plugins.extendedClientSettings ? ctx.plugins.extendedClientSettings(env.extendedSettings) : {}
|
||||||
|
, activeProfile ..... calculated from treatments or missing
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
public class NSStatus {
|
||||||
|
private JSONObject data;
|
||||||
|
|
||||||
|
public NSStatus(JSONObject obj) {
|
||||||
|
this.data = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName () { return getStringOrNull("name"); }
|
||||||
|
public String getVersion () { return getStringOrNull("version"); }
|
||||||
|
public Integer getVersionNum () { return getIntegerOrNull("versionNum"); }
|
||||||
|
public Date getServerTime () { return getDateOrNull("versionNum"); }
|
||||||
|
public boolean getApiEnabled () { return getBooleanOrNull("apiEnabled"); }
|
||||||
|
public boolean getCareportalEnabled () { return getBooleanOrNull("careportalEnabled"); }
|
||||||
|
public boolean getBoluscalcEnabled () { return getBooleanOrNull("boluscalcEnabled"); }
|
||||||
|
public String getHead () { return getStringOrNull("head"); }
|
||||||
|
public String getSettings () { return getStringOrNull("settings"); }
|
||||||
|
public String getExtendedSettings () { return getStringOrNull("extendedSettings"); }
|
||||||
|
public String getActiveProfile () { return getStringOrNull("activeProfile"); }
|
||||||
|
|
||||||
|
private String getStringOrNull(String key) {
|
||||||
|
String ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getString(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Integer getIntegerOrNull(String key) {
|
||||||
|
Integer ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getInt(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Long getLongOrNull(String key) {
|
||||||
|
Long ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getLong(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Date getDateOrNull(String key) {
|
||||||
|
Date ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = new Date(data.getString(key));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private boolean getBooleanOrNull(String key) {
|
||||||
|
boolean ret = false;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getBoolean(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
public JSONObject getData () { return data; }
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,89 @@
|
||||||
|
package info.nightscout.client.data;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
public class NSTreatment {
|
||||||
|
private JSONObject data;
|
||||||
|
private String action = null; // "update", "remove" or null (add)
|
||||||
|
|
||||||
|
public NSTreatment(JSONObject obj) {
|
||||||
|
this.data = obj;
|
||||||
|
this.action = getStringOrNull("action");
|
||||||
|
this.data.remove("action");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStringOrNull(String key) {
|
||||||
|
String ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getString(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Double getDoubleOrNull(String key) {
|
||||||
|
Double ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getDouble(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Integer getIntegerOrNull(String key) {
|
||||||
|
Integer ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getInt(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Long getLongOrNull(String key) {
|
||||||
|
Long ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = data.getLong(key);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
private Date getDateOrNull(String key) {
|
||||||
|
Date ret = null;
|
||||||
|
if (data.has(key)) {
|
||||||
|
try {
|
||||||
|
ret = new Date(data.getString(key));
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
public String getAction() { return action; }
|
||||||
|
public JSONObject getData() { return data; }
|
||||||
|
public String get_id() { return getStringOrNull("_id"); }
|
||||||
|
public String getEnteredBy() { return getStringOrNull("enteredBy"); }
|
||||||
|
public String getEventType() { return getStringOrNull("eventType"); }
|
||||||
|
public Integer getHapp_id() { return getIntegerOrNull("happ_id"); }
|
||||||
|
public Integer getDuration() { return getIntegerOrNull("duration"); }
|
||||||
|
public Integer getMgdl() { return getIntegerOrNull("mgdl"); }
|
||||||
|
public Double getAbsolute() { return getDoubleOrNull("absolute"); }
|
||||||
|
public Long getMills() { return getLongOrNull("mills"); }
|
||||||
|
public Date getCreated_at() { return getDateOrNull("created_at"); }
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
package info.nightscout.client.receivers;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
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 org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||||
|
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||||
|
import info.nightscout.client.broadcasts.Intents;
|
||||||
|
import info.nightscout.client.data.NSProfile;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.db.Treatment;
|
||||||
|
|
||||||
|
public class NSClientDataReceiver extends BroadcastReceiver {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(NSClientDataReceiver.class);
|
||||||
|
public NSClientDataReceiver() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
Bundle bundles = intent.getExtras();
|
||||||
|
if (bundles == null) return;
|
||||||
|
|
||||||
|
|
||||||
|
// Handle profile
|
||||||
|
if (intent.getAction().equals(Intents.ACTION_NEW_PROFILE)){
|
||||||
|
try {
|
||||||
|
String activeProfile = bundles.getString("activeprofile");
|
||||||
|
String profile = bundles.getString("profile");
|
||||||
|
NSProfile nsProfile = new NSProfile(new JSONObject(profile), activeProfile);
|
||||||
|
MainApp.instance().setNSProfile(nsProfile);
|
||||||
|
MainApp.instance().setActiveProfile(activeProfile);
|
||||||
|
storeNSProfile();
|
||||||
|
if (MainApp.getActivePump() != null) {
|
||||||
|
MainApp.getActivePump().setNewBasalProfile();
|
||||||
|
} else {
|
||||||
|
log.error("No active pump selected");
|
||||||
|
}
|
||||||
|
log.debug("Received profile: " + activeProfile + " " + profile);
|
||||||
|
MainApp.bus().post(new EventNewBasalProfile());
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (intent.getAction().equals(Intents.ACTION_NEW_TREATMENT)) {
|
||||||
|
try {
|
||||||
|
String trstring = bundles.getString("treatment");
|
||||||
|
JSONObject trJson = new JSONObject(trstring);
|
||||||
|
if (!trJson.has("insulin") && !trJson.has("carbs")) {
|
||||||
|
log.debug("ADD: Uninterested treatment: " + trstring);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Treatment stored = null;
|
||||||
|
trJson = new JSONObject(trstring);
|
||||||
|
String _id = trJson.getString("_id");
|
||||||
|
|
||||||
|
if (trJson.has("timeIndex")) {
|
||||||
|
log.debug("ADD: timeIndex found: " + trstring);
|
||||||
|
stored = findByTimeIndex(trJson.getLong("timeIndex"));
|
||||||
|
} else {
|
||||||
|
stored = findById(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stored != null) {
|
||||||
|
log.debug("ADD: Existing treatment: " + trstring);
|
||||||
|
if (trJson.has("timeIndex")) {
|
||||||
|
stored._id = _id;
|
||||||
|
MainApp.getDbHelper().getDaoTreatments().update(stored);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log.debug("ADD: New treatment: " + trstring);
|
||||||
|
Treatment treatment = new Treatment();
|
||||||
|
treatment._id = _id;
|
||||||
|
treatment.carbs = trJson.has("carbs") ? trJson.getDouble("carbs") : 0;
|
||||||
|
treatment.insulin = trJson.has("insulin") ? trJson.getDouble("insulin") : 0d;
|
||||||
|
treatment.created_at = new Date(trJson.getLong("mills"));
|
||||||
|
treatment.setTimeIndex(treatment.getTimeIndex());
|
||||||
|
try {
|
||||||
|
MainApp.getDbHelper().getDaoTreatments().create(treatment);
|
||||||
|
log.debug("ADD: Stored treatment: " + treatment.log());
|
||||||
|
MainApp.bus().post(new EventTreatmentChange());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intent.getAction().equals(Intents.ACTION_CHANGED_TREATMENT)) {
|
||||||
|
try {
|
||||||
|
String trstring = bundles.getString("treatment");
|
||||||
|
JSONObject trJson = new JSONObject(trstring);
|
||||||
|
if (!trJson.has("insulin") && !trJson.has("carbs")) {
|
||||||
|
log.debug("CHANGE: Uninterested treatment: " + trstring);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
trJson = new JSONObject(trstring);
|
||||||
|
String _id = trJson.getString("_id");
|
||||||
|
|
||||||
|
Treatment stored;
|
||||||
|
|
||||||
|
if (trJson.has("timeIndex")) {
|
||||||
|
log.debug("ADD: timeIndex found: " + trstring);
|
||||||
|
stored = findByTimeIndex(trJson.getLong("timeIndex"));
|
||||||
|
} else {
|
||||||
|
stored = findById(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stored != null) {
|
||||||
|
log.debug("CHANGE: Existing treatment: " + trstring);
|
||||||
|
stored._id = _id;
|
||||||
|
stored.carbs = trJson.has("carbs") ? trJson.getDouble("carbs") : 0;
|
||||||
|
stored.insulin = trJson.has("insulin") ? trJson.getDouble("insulin") : 0d;
|
||||||
|
stored.created_at = new Date(trJson.getLong("mills"));
|
||||||
|
MainApp.getDbHelper().getDaoTreatments().update(stored);
|
||||||
|
MainApp.bus().post(new EventTreatmentChange());
|
||||||
|
} else {
|
||||||
|
log.debug("CHANGE: New treatment: " + trstring);
|
||||||
|
Treatment treatment = new Treatment();
|
||||||
|
treatment._id = _id;
|
||||||
|
treatment.carbs = trJson.has("carbs") ? trJson.getDouble("carbs") : 0;
|
||||||
|
treatment.insulin = trJson.has("insulin") ? trJson.getDouble("insulin") : 0d;
|
||||||
|
//treatment.created_at = DateUtil.fromISODateString(trJson.getString("created_at"));
|
||||||
|
treatment.created_at = new Date(trJson.getLong("mills"));
|
||||||
|
treatment.setTimeIndex(treatment.getTimeIndex());
|
||||||
|
try {
|
||||||
|
MainApp.getDbHelper().getDaoTreatments().create(treatment);
|
||||||
|
log.debug("CHANGE: Stored treatment: " + treatment.log());
|
||||||
|
MainApp.bus().post(new EventTreatmentChange());
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intent.getAction().equals(Intents.ACTION_REMOVED_TREATMENT)) {
|
||||||
|
try {
|
||||||
|
if (bundles.containsKey("treatment")) {
|
||||||
|
String trstring = bundles.getString("treatment");
|
||||||
|
JSONObject trJson = new JSONObject(trstring);
|
||||||
|
String _id = trJson.getString("_id");
|
||||||
|
removeTreatmentFromDb(_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 _id = trJson.getString("_id");
|
||||||
|
removeTreatmentFromDb(_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void storeNSProfile() {
|
||||||
|
SharedPreferences settings = MainApp.instance().getApplicationContext().getSharedPreferences(MainApp.instance().PREFS_NAME, 0);
|
||||||
|
SharedPreferences.Editor editor = settings.edit();
|
||||||
|
editor.putString("profile", MainApp.instance().getNSProfile().getData().toString());
|
||||||
|
editor.putString("activeProfile", MainApp.instance().getActiveProfile());
|
||||||
|
editor.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Treatment findById(String _id) {
|
||||||
|
try {
|
||||||
|
QueryBuilder<Treatment, String> qb = null;
|
||||||
|
Dao<Treatment, Long> daoTreatments = MainApp.getDbHelper().getDaoTreatments();
|
||||||
|
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.eq("_id", _id);
|
||||||
|
queryBuilder.limit(10);
|
||||||
|
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
|
||||||
|
List<Treatment> trList = daoTreatments.query(preparedQuery);
|
||||||
|
if (trList.size() != 1) {
|
||||||
|
//log.debug("Treatment findById query size: " + trList.size());
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
//log.debug("Treatment findById found: " + trList.get(0).log());
|
||||||
|
return trList.get(0);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Treatment findByTimeIndex(Long timeIndex) {
|
||||||
|
try {
|
||||||
|
QueryBuilder<Treatment, String> qb = null;
|
||||||
|
Dao<Treatment, Long> daoTreatments = MainApp.getDbHelper().getDaoTreatments();
|
||||||
|
QueryBuilder<Treatment, Long> queryBuilder = daoTreatments.queryBuilder();
|
||||||
|
Where where = queryBuilder.where();
|
||||||
|
where.eq("timeIndex", timeIndex);
|
||||||
|
queryBuilder.limit(10);
|
||||||
|
PreparedQuery<Treatment> preparedQuery = queryBuilder.prepare();
|
||||||
|
List<Treatment> trList = daoTreatments.query(preparedQuery);
|
||||||
|
if (trList.size() != 1) {
|
||||||
|
log.debug("Treatment findByTimeIndex query size: " + trList.size());
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
log.debug("Treatment findByTimeIndex found: " + trList.get(0).log());
|
||||||
|
return trList.get(0);
|
||||||
|
}
|
||||||
|
} catch (SQLException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTreatmentFromDb(String _id) throws SQLException {
|
||||||
|
Treatment stored = findById(_id);
|
||||||
|
if (stored != null) {
|
||||||
|
log.debug("REMOVE: Existing treatment (removing): " + _id);
|
||||||
|
MainApp.getDbHelper().getDaoTreatments().delete(stored);
|
||||||
|
MainApp.bus().post(new EventTreatmentChange());
|
||||||
|
} else {
|
||||||
|
log.debug("REMOVE: Not stored treatment (ignoring): " + _id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
52
app/src/main/java/info/nightscout/utils/DateUtil.java
Normal file
52
app/src/main/java/info/nightscout/utils/DateUtil.java
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
package info.nightscout.utils;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Class DateUtil. A simple wrapper around SimpleDateFormat to ease the handling of iso date string <-> date obj
|
||||||
|
* with TZ
|
||||||
|
*/
|
||||||
|
public class DateUtil
|
||||||
|
{
|
||||||
|
|
||||||
|
/** The date format in iso. */
|
||||||
|
public static String FORMAT_DATE_ISO="yyyy-MM-dd'T'HH:mm:ssZ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes in an ISO date string of the following format:
|
||||||
|
* yyyy-mm-ddThh:mm:ss.ms+HoMo
|
||||||
|
*
|
||||||
|
* @param isoDateString the iso date string
|
||||||
|
* @return the date
|
||||||
|
* @throws Exception the exception
|
||||||
|
*/
|
||||||
|
public static Date fromISODateString(String isoDateString)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
DateFormat f = new SimpleDateFormat(FORMAT_DATE_ISO);
|
||||||
|
return f.parse(isoDateString);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render date
|
||||||
|
*
|
||||||
|
* @param date the date obj
|
||||||
|
* @param format - if not specified, will use FORMAT_DATE_ISO
|
||||||
|
* @param tz - tz to set to, if not specified uses local timezone
|
||||||
|
* @return the iso-formatted date string
|
||||||
|
*/
|
||||||
|
public static String toISOString(Date date, String format, TimeZone tz)
|
||||||
|
{
|
||||||
|
if( format == null ) format = FORMAT_DATE_ISO;
|
||||||
|
if( tz == null ) tz = TimeZone.getDefault();
|
||||||
|
DateFormat f = new SimpleDateFormat(format);
|
||||||
|
f.setTimeZone(tz);
|
||||||
|
return f.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toISOString(Date date)
|
||||||
|
{ return toISOString(date,FORMAT_DATE_ISO,TimeZone.getTimeZone("UTC")); }
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/objectives_cardview"
|
android:id="@+id/objectives_cardview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
card_view:cardBackgroundColor="@color/cardColorBackground"
|
card_view:cardBackgroundColor="@color/cardColorBackground"
|
||||||
card_view:cardCornerRadius="6dp"
|
card_view:cardCornerRadius="6dp"
|
||||||
|
|
106
app/src/main/res/layout/profileviewer_fragment.xml
Normal file
106
app/src/main/res/layout/profileviewer_fragment.xml
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".plugins.ProfileViewer.ProfileViewerFragment">
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_noprofile"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_noprofile_text"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:textColor="@android:color/holo_red_light"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:gravity="center_horizontal" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_activeprofile_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_activeprofile"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="25dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_dia_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_dia"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="25dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_ic_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_ic"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="25dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_isf_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_isf"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="25dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_basal_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_basal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="25dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/profileview_target_label"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
|
android:layout_marginLeft="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/profileview_target"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="15dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
|
@ -3,7 +3,7 @@
|
||||||
<color name="colorPrimary">#3F51B5</color>
|
<color name="colorPrimary">#3F51B5</color>
|
||||||
<color name="colorPrimaryDark">#303F9F</color>
|
<color name="colorPrimaryDark">#303F9F</color>
|
||||||
<color name="colorAccent">#FF4081</color>
|
<color name="colorAccent">#FF4081</color>
|
||||||
<color name="cardColorBackground">#121212</color>
|
|
||||||
|
|
||||||
|
<color name="cardColorBackground">#121212</color>
|
||||||
<color name="cardObjectiveText">#779ECB</color>
|
<color name="cardObjectiveText">#779ECB</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -27,5 +27,12 @@
|
||||||
<string name="objectives_gate_label_string">Gate:</string>
|
<string name="objectives_gate_label_string">Gate:</string>
|
||||||
<string name="objectives_button_start">Start</string>
|
<string name="objectives_button_start">Start</string>
|
||||||
<string name="objectives_button_verify">Verify</string>
|
<string name="objectives_button_verify">Verify</string>
|
||||||
|
<string name="profileview_dia_label">DIA:</string>
|
||||||
|
<string name="profileview_activeprofile_label">Active profile:</string>
|
||||||
|
<string name="profileview_ic_label">IC:</string>
|
||||||
|
<string name="profileview_isf_label">ISF:</string>
|
||||||
|
<string name="profileview_basal_label">Basal:</string>
|
||||||
|
<string name="profileview_target_label">Target:</string>
|
||||||
|
<string name="profileview_noprofile_text">NO PROFILE SET</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue