receive BGs from xDrip and NSClient
This commit is contained in:
parent
04f1b37c51
commit
701e6a2055
27 changed files with 1572 additions and 384 deletions
|
@ -3,8 +3,9 @@
|
|||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="distributionType" value="LOCAL" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||
<option name="gradleHome" value="C:\Program Files\Android\Android Studio\gradle\gradle-2.10" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$" />
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="AndroidLintRtlHardcoded" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="AndroidLintUselessParent" enabled="false" level="WARNING" enabled_by_default="false" />
|
||||
<inspection_tool class="AndroidLintValidFragment" enabled="false" level="ERROR" enabled_by_default="false" />
|
||||
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
|
||||
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
|
||||
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
|
@ -1,7 +0,0 @@
|
|||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="PROJECT_PROFILE" value="Project Default" />
|
||||
<option name="USE_PROJECT_PROFILE" value="true" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
|
@ -43,20 +43,4 @@
|
|||
<component name="ProjectType">
|
||||
<option name="id" value="Android" />
|
||||
</component>
|
||||
<component name="masterDetails">
|
||||
<states>
|
||||
<state key="ProjectJDKs.UI">
|
||||
<settings>
|
||||
<last-edited>1.8</last-edited>
|
||||
<splitter-proportions>
|
||||
<option name="proportions">
|
||||
<list>
|
||||
<option value="0.2" />
|
||||
</list>
|
||||
</option>
|
||||
</splitter-proportions>
|
||||
</settings>
|
||||
</state>
|
||||
</states>
|
||||
</component>
|
||||
</project>
|
|
@ -14,6 +14,9 @@
|
|||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<!-- To receive data from xdrip. -->
|
||||
<uses-permission android:name="com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE" />
|
||||
|
||||
<application
|
||||
android:name=".MainApp"
|
||||
android:allowBackup="true"
|
||||
|
@ -34,7 +37,6 @@
|
|||
android:name="info.nightscout.client.receivers.NSClientDataReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="info.nightscout.client.NEW_TREATMENT" />
|
||||
<action android:name="info.nightscout.client.CHANGED_TREATMENT" />
|
||||
|
@ -45,6 +47,21 @@
|
|||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Receiver from xDrip -->
|
||||
<receiver
|
||||
android:name=".receivers.xDripReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.eveningoutpost.dexdrip.BgEstimate" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<!-- Service processing incomming data -->
|
||||
<service
|
||||
android:name=".Services.DataService"
|
||||
android:exported="false"></service>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
13
app/src/main/java/info/nightscout/androidaps/Constants.java
Normal file
13
app/src/main/java/info/nightscout/androidaps/Constants.java
Normal file
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
/**
|
||||
* Created by mike on 07.06.2016.
|
||||
*/
|
||||
public class Constants {
|
||||
public static final String MGDL = "mg/dl"; // This is Nightscout representation
|
||||
public static final String MMOL = "mmol";
|
||||
|
||||
public static final double MMOLL_TO_MGDL = 18.0182;
|
||||
public static final double MGDL_TO_MMOLL = 1 / MMOLL_TO_MGDL;
|
||||
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package info.nightscout.androidaps;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
|
@ -12,15 +10,12 @@ 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.plugins.TempBasals.TempBasalsFragment;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
|
||||
import info.nightscout.androidaps.tabs.*;
|
||||
import info.nightscout.androidaps.plugins.Objectives.ObjectivesFragment;
|
||||
import info.nightscout.androidaps.plugins.Test.TestFragment;
|
||||
import info.nightscout.client.broadcasts.Intents;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements ObjectivesFragment.OnFragmentInteractionListener,
|
||||
|
@ -33,6 +28,10 @@ public class MainActivity extends AppCompatActivity
|
|||
private ViewPager mPager;
|
||||
private TabPageAdapter mAdapter;
|
||||
|
||||
public static TreatmentsFragment treatmentsFragment;
|
||||
public static TempBasalsFragment tempBasalsFragment;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
@ -41,8 +40,8 @@ public class MainActivity extends AppCompatActivity
|
|||
// Register all tabs in app here
|
||||
mAdapter = new TabPageAdapter(getSupportFragmentManager());
|
||||
mAdapter.registerNewFragment("Test", TestFragment.newInstance());
|
||||
mAdapter.registerNewFragment("Treatments", TreatmentsFragment.newInstance());
|
||||
mAdapter.registerNewFragment("TempBasals", TempBasalsFragment.newInstance());
|
||||
mAdapter.registerNewFragment("Treatments", treatmentsFragment = TreatmentsFragment.newInstance());
|
||||
mAdapter.registerNewFragment("TempBasals", tempBasalsFragment = TempBasalsFragment.newInstance());
|
||||
mAdapter.registerNewFragment("Profile", ProfileViewerFragment.newInstance());
|
||||
mAdapter.registerNewFragment("Objectives", ObjectivesFragment.newInstance());
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
|
|||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.data.Pump;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
|
||||
import info.nightscout.client.data.NSProfile;
|
||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||
|
||||
|
|
|
@ -0,0 +1,391 @@
|
|||
package info.nightscout.androidaps.Services;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
|
||||
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.MainApp;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||
import info.nightscout.androidaps.tabs.Config;
|
||||
import info.nightscout.client.data.NSProfile;
|
||||
import info.nightscout.client.data.NSSgv;
|
||||
|
||||
|
||||
public class DataService extends IntentService {
|
||||
private static Logger log = LoggerFactory.getLogger(DataService.class);
|
||||
|
||||
Handler mHandler;
|
||||
private HandlerThread mHandlerThread;
|
||||
|
||||
public DataService() {
|
||||
super("DataService");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onHandleIntent");
|
||||
|
||||
if (intent != null) {
|
||||
final String action = intent.getAction();
|
||||
if (Intents.ACTION_NEW_BG_ESTIMATE.equals(action)) {
|
||||
handleNewDataFromXDrip(intent);
|
||||
} else if (Intents.ACTION_NEW_PROFILE.equals(action) ||
|
||||
Intents.ACTION_NEW_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_CHANGED_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_REMOVED_TREATMENT.equals(action) ||
|
||||
Intents.ACTION_NEW_SGV.equals(action)
|
||||
) {
|
||||
handleNewDataFromNSClient(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
super.onStartCommand(intent, flags, startId);
|
||||
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onStartCommand");
|
||||
|
||||
if (mHandlerThread == null) {
|
||||
if (Config.detailedLog)
|
||||
log.debug("Creating handler thread");
|
||||
|
||||
this.mHandlerThread = new HandlerThread(DataService.class.getSimpleName() + "Handler");
|
||||
mHandlerThread.start();
|
||||
|
||||
this.mHandler = new Handler(mHandlerThread.getLooper());
|
||||
|
||||
registerBus();
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
MainApp.bus().unregister(this);
|
||||
}
|
||||
|
||||
private void registerBus() {
|
||||
try {
|
||||
MainApp.bus().unregister(this);
|
||||
} catch (RuntimeException x) {
|
||||
// Ignore
|
||||
}
|
||||
MainApp.bus().register(this);
|
||||
}
|
||||
|
||||
private void handleNewDataFromXDrip(Intent intent) {
|
||||
Bundle bundle = intent.getExtras();
|
||||
if (bundle == null) return;
|
||||
|
||||
BgReading bgReading = new BgReading();
|
||||
|
||||
bgReading.value = bundle.getDouble(Intents.EXTRA_BG_ESTIMATE);
|
||||
bgReading.slope = bundle.getDouble(Intents.EXTRA_BG_SLOPE);
|
||||
bgReading.battery_level = bundle.getInt(Intents.EXTRA_SENSOR_BATTERY);
|
||||
bgReading.timestamp = bundle.getLong(Intents.EXTRA_TIMESTAMP);
|
||||
bgReading.raw = bundle.getDouble(Intents.EXTRA_RAW);
|
||||
|
||||
if (Config.logIncommingBG)
|
||||
log.debug("XDRIPREC BG " + bgReading.toString());
|
||||
|
||||
try {
|
||||
MainApp.instance().getDbHelper().getDaoBgReadings().update(bgReading);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
MainApp.bus().post(new EventNewBG());
|
||||
}
|
||||
|
||||
private void handleNewDataFromNSClient(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");
|
||||
}
|
||||
if (Config.logIncommingData)
|
||||
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")) {
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: Uninterested treatment: " + trstring);
|
||||
return;
|
||||
}
|
||||
|
||||
Treatment stored = null;
|
||||
trJson = new JSONObject(trstring);
|
||||
String _id = trJson.getString("_id");
|
||||
|
||||
if (trJson.has("timeIndex")) {
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: timeIndex found: " + trstring);
|
||||
stored = findByTimeIndex(trJson.getLong("timeIndex"));
|
||||
} else {
|
||||
stored = findById(_id);
|
||||
}
|
||||
|
||||
if (stored != null) {
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: Existing treatment: " + trstring);
|
||||
if (trJson.has("timeIndex")) {
|
||||
stored._id = _id;
|
||||
MainApp.getDbHelper().getDaoTreatments().update(stored);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
if (Config.logIncommingData)
|
||||
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);
|
||||
if (Config.logIncommingData)
|
||||
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")) {
|
||||
if (Config.logIncommingData)
|
||||
log.debug("CHANGE: Uninterested treatment: " + trstring);
|
||||
return;
|
||||
}
|
||||
trJson = new JSONObject(trstring);
|
||||
String _id = trJson.getString("_id");
|
||||
|
||||
Treatment stored;
|
||||
|
||||
if (trJson.has("timeIndex")) {
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: timeIndex found: " + trstring);
|
||||
stored = findByTimeIndex(trJson.getLong("timeIndex"));
|
||||
} else {
|
||||
stored = findById(_id);
|
||||
}
|
||||
|
||||
if (stored != null) {
|
||||
if (Config.logIncommingData)
|
||||
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 {
|
||||
if (Config.logIncommingData)
|
||||
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);
|
||||
if (Config.logIncommingData)
|
||||
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);
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventTreatmentChange());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_SGV)) {
|
||||
try {
|
||||
if (bundles.containsKey("sgv")) {
|
||||
String sgvstring = bundles.getString("sgv");
|
||||
JSONObject sgvJson = new JSONObject(sgvstring);
|
||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
||||
BgReading bgReading = new BgReading(nsSgv);
|
||||
MainApp.getDbHelper().getDaoBgReadings().update(bgReading);
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: Stored new BG: " + bgReading.toString());
|
||||
}
|
||||
|
||||
if (bundles.containsKey("sgvs")) {
|
||||
String sgvstring = bundles.getString("sgvs");
|
||||
JSONArray jsonArray = new JSONArray(sgvstring);
|
||||
for (int i = 0; i < jsonArray.length(); i++) {
|
||||
JSONObject sgvJson = jsonArray.getJSONObject(i);
|
||||
NSSgv nsSgv = new NSSgv(sgvJson);
|
||||
BgReading bgReading = new BgReading(nsSgv);
|
||||
MainApp.getDbHelper().getDaoBgReadings().update(bgReading);
|
||||
if (Config.logIncommingData)
|
||||
log.debug("ADD: Stored new BG: " + bgReading.toString());
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventTreatmentChange());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
MainApp.bus().post(new EventNewBG());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package info.nightscout.androidaps.Services;
|
||||
|
||||
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";
|
||||
String ACTION_RESTART = "info.nightscout.client.RESTART";
|
||||
|
||||
// xDrip -> App
|
||||
String RECEIVER_PERMISSION = "com.eveningoutpost.dexdrip.permissions.RECEIVE_BG_ESTIMATE";
|
||||
|
||||
String ACTION_NEW_BG_ESTIMATE = "com.eveningoutpost.dexdrip.BgEstimate";
|
||||
String EXTRA_BG_ESTIMATE = "com.eveningoutpost.dexdrip.Extras.BgEstimate";
|
||||
String EXTRA_BG_SLOPE = "com.eveningoutpost.dexdrip.Extras.BgSlope";
|
||||
String EXTRA_BG_SLOPE_NAME = "com.eveningoutpost.dexdrip.Extras.BgSlopeName";
|
||||
String EXTRA_SENSOR_BATTERY = "com.eveningoutpost.dexdrip.Extras.SensorBattery";
|
||||
String EXTRA_TIMESTAMP = "com.eveningoutpost.dexdrip.Extras.Time";
|
||||
String EXTRA_RAW = "com.eveningoutpost.dexdrip.Extras.Raw";
|
||||
|
||||
String ACTION_NEW_BG_ESTIMATE_NO_DATA = "com.eveningoutpost.dexdrip.BgEstimateNoData";
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
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.text.DecimalFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.client.data.NSCal;
|
||||
import info.nightscout.client.data.NSSgv;
|
||||
|
||||
@DatabaseTable(tableName = "BgReadings")
|
||||
public class BgReading {
|
||||
private static Logger log = LoggerFactory.getLogger(BgReading.class);
|
||||
public static final DecimalFormat mmolFormat = new DecimalFormat("0.0");
|
||||
public static final DecimalFormat mgdlFormat = new DecimalFormat("0");
|
||||
|
||||
public long getTimeIndex() {
|
||||
return (long) Math.ceil(timestamp / 60000d);
|
||||
}
|
||||
|
||||
public void setTimeIndex(long timeIndex) {
|
||||
this.timestamp = timeIndex;
|
||||
}
|
||||
|
||||
@DatabaseField(id = true, useGetSet = true)
|
||||
public long timeIndex;
|
||||
|
||||
@DatabaseField
|
||||
public long timestamp;
|
||||
|
||||
@DatabaseField
|
||||
public double value;
|
||||
|
||||
@DatabaseField
|
||||
public double slope;
|
||||
|
||||
@DatabaseField
|
||||
public double raw;
|
||||
|
||||
@DatabaseField
|
||||
public int battery_level;
|
||||
|
||||
public BgReading() {}
|
||||
|
||||
public BgReading(NSSgv sgv) {
|
||||
timestamp = sgv.getMills();
|
||||
value = sgv.getMgdl();
|
||||
raw = sgv.getFiltered();
|
||||
}
|
||||
|
||||
public String valInUnit(String units) {
|
||||
DecimalFormat formatMmol = new DecimalFormat("0.0");
|
||||
DecimalFormat formatMgdl = new DecimalFormat("0");
|
||||
if (units.equals(Constants.MGDL)) return formatMgdl.format(value);
|
||||
else return formatMmol.format(value/18d);
|
||||
}
|
||||
|
||||
public Double valueToUnits(String units) {
|
||||
if (units.equals(Constants.MGDL))
|
||||
return value;
|
||||
else
|
||||
return value * Constants.MGDL_TO_MMOLL;
|
||||
}
|
||||
|
||||
public String valueToUnitsToString(String units) {
|
||||
if (units.equals(Constants.MGDL)) return mgdlFormat.format(value);
|
||||
else return mmolFormat.format(value * Constants.MGDL_TO_MMOLL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TempBasal{" +
|
||||
"timeIndex=" + timeIndex +
|
||||
", timestamp=" + timestamp +
|
||||
", date=" + new Date(timestamp) +
|
||||
", value=" + value +
|
||||
", slope=" + slope +
|
||||
", raw=" + raw +
|
||||
", battery_level=" + battery_level +
|
||||
'}';
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package info.nightscout.androidaps.db;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
|
@ -8,18 +9,22 @@ import android.database.sqlite.SQLiteDatabase;
|
|||
|
||||
import com.j256.ormlite.android.apptools.OrmLiteSqliteOpenHelper;
|
||||
import com.j256.ormlite.dao.Dao;
|
||||
import com.j256.ormlite.stmt.PreparedQuery;
|
||||
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;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
||||
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 = 2;
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
public DatabaseHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
@ -32,6 +37,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
log.info("onCreate");
|
||||
TableUtils.createTableIfNotExists(connectionSource, TempBasal.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||
// TODO: add bg support
|
||||
} catch (SQLException e) {
|
||||
log.error(DatabaseHelper.class.getName(), "Can't create database", e);
|
||||
|
@ -45,6 +51,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
log.info(DatabaseHelper.class.getName(), "onUpgrade");
|
||||
TableUtils.dropTable(connectionSource, TempBasal.class, true);
|
||||
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||
TableUtils.dropTable(connectionSource, BgReading.class, true);
|
||||
onCreate(database, connectionSource);
|
||||
} catch (SQLException e) {
|
||||
log.error(DatabaseHelper.class.getName(), "Can't drop databases", e);
|
||||
|
@ -64,8 +71,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
try {
|
||||
TableUtils.dropTable(connectionSource, TempBasal.class, true);
|
||||
TableUtils.dropTable(connectionSource, Treatment.class, true);
|
||||
TableUtils.dropTable(connectionSource, BgReading.class, true);
|
||||
TableUtils.createTableIfNotExists(connectionSource, TempBasal.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, Treatment.class);
|
||||
TableUtils.createTableIfNotExists(connectionSource, BgReading.class);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -89,4 +98,46 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
|
|||
return getDao(Treatment.class);
|
||||
}
|
||||
|
||||
public Dao<BgReading, Long> getDaoBgReadings() throws SQLException {
|
||||
return getDao(BgReading.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return last BgReading from database or null if db is empty
|
||||
*/
|
||||
public BgReading lastBg() {
|
||||
List<BgReading> bgList = null;
|
||||
|
||||
try {
|
||||
Dao<BgReading, Long> daoBgReadings = MainApp.getDbHelper().getDaoBgReadings();
|
||||
QueryBuilder<BgReading, Long> queryBuilder = daoBgReadings.queryBuilder();
|
||||
queryBuilder.orderBy("timeIndex", false);
|
||||
queryBuilder.limit(1l);
|
||||
PreparedQuery<BgReading> preparedQuery = queryBuilder.prepare();
|
||||
bgList = daoBgReadings.query(preparedQuery);
|
||||
|
||||
} catch (SQLException e) {
|
||||
log.debug(e.getMessage(), e);
|
||||
}
|
||||
if (bgList.size() > 0)
|
||||
return bgList.get(0);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return bg reading if not old ( <9 min )
|
||||
* or null if older
|
||||
*/
|
||||
public BgReading actualBg() {
|
||||
BgReading lastBg = lastBg();
|
||||
|
||||
if (lastBg == null)
|
||||
return null;
|
||||
|
||||
if (lastBg.timestamp > new Date().getTime() - 9 * 60 * 1000)
|
||||
return lastBg;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.client.broadcasts.Intents;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.client.data.NSProfile;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
|
|
@ -67,6 +67,7 @@ public class ProfileViewerFragment extends Fragment {
|
|||
NSProfile profile = MainApp.getNSProfile();
|
||||
if (profile == null) {
|
||||
noProfile.setVisibility(View.VISIBLE);
|
||||
return;
|
||||
} else {
|
||||
noProfile.setVisibility(View.GONE);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ public class TempBasalsFragment extends Fragment {
|
|||
TextView iobTotal;
|
||||
TextView activityTotal;
|
||||
|
||||
public long lastCalculationTimestamp = 0;
|
||||
public Iob lastCalculation;
|
||||
|
||||
private static DecimalFormat formatNumber0decimalplaces = new DecimalFormat("0");
|
||||
private static DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||
private static DecimalFormat formatNumber3decimalplaces = new DecimalFormat("0.000");
|
||||
|
@ -86,6 +89,15 @@ public class TempBasalsFragment extends Fragment {
|
|||
updateTotalIOB();
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalculate IOB if value is older than 1 minute
|
||||
*/
|
||||
public void updateTotalIOBIfNeeded() {
|
||||
if (lastCalculationTimestamp > new Date().getTime() - 60 * 1000)
|
||||
return;
|
||||
updateTotalIOB();
|
||||
}
|
||||
|
||||
private void updateTotalIOB() {
|
||||
Iob total = new Iob();
|
||||
for (Integer pos = 0; pos < tempBasals.size(); pos++) {
|
||||
|
@ -253,16 +265,21 @@ public class TempBasalsFragment extends Fragment {
|
|||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBG ev) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateTotalIOB();
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUserVisibleHint(boolean isVisibleToUser) {
|
||||
super.setUserVisibleHint(isVisibleToUser);
|
||||
|
||||
if (isVisibleToUser)
|
||||
updateTotalIOB();
|
||||
updateTotalIOBIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package info.nightscout.androidaps.plugins.Treatments.Dialogs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.view.*;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class NewTreatmentDialogFragment extends DialogFragment implements OnClickListener {
|
||||
|
||||
Button deliverButton;
|
||||
Communicator communicator;
|
||||
TextView insulin;
|
||||
TextView carbs;
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
|
||||
super.onAttach(activity);
|
||||
|
||||
if (activity instanceof Communicator) {
|
||||
communicator = (Communicator) getActivity();
|
||||
|
||||
} else {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implemenet NewTreatmentDialogFragment.Communicator");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.treatments_newtreatment_fragment, null, false);
|
||||
|
||||
deliverButton = (Button) view.findViewById(R.id.treatments_newtreatment_deliverbutton);
|
||||
|
||||
deliverButton.setOnClickListener(this);
|
||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
insulin = (TextView) view.findViewById(R.id.treatments_newtreatment_insulinamount);
|
||||
carbs = (TextView) view.findViewById(R.id.treatments_newtreatment_carbsamount);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.treatments_newtreatment_deliverbutton:
|
||||
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
Double maxbolus = Double.parseDouble(SP.getString("safety_maxbolus", "3"));
|
||||
Double maxcarbs = Double.parseDouble(SP.getString("safety_maxcarbs", "48"));
|
||||
|
||||
|
||||
String insulinText = this.insulin.getText().toString();
|
||||
String carbsText = this.carbs.getText().toString();
|
||||
Double insulin = Double.parseDouble(!insulinText.equals("") ? this.insulin.getText().toString() : "0");
|
||||
Double carbs = Double.parseDouble(!carbsText.equals("") ? this.carbs.getText().toString() : "0");
|
||||
if (insulin > maxbolus) {
|
||||
this.insulin.setText("");
|
||||
} else if (carbs > maxcarbs) {
|
||||
this.carbs.setText("");
|
||||
} else if (insulin > 0d || carbs > 0d) {
|
||||
dismiss();
|
||||
communicator.treatmentDeliverRequest(insulin, carbs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface Communicator {
|
||||
void treatmentDeliverRequest(Double insulin, Double carbs);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,295 @@
|
|||
package info.nightscout.androidaps.plugins.Treatments.Dialogs;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.DialogFragment;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.*;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsFragment;
|
||||
import info.nightscout.client.data.NSProfile;
|
||||
import info.nightscout.utils.*;
|
||||
|
||||
public class WizardDialogFragment extends DialogFragment implements OnClickListener {
|
||||
|
||||
Button wizardDialogDeliverButton;
|
||||
Communicator communicator;
|
||||
TextView correctionInput;
|
||||
TextView carbsInput;
|
||||
TextView bgInput;
|
||||
TextView bg, bgInsulin, bgUnits;
|
||||
CheckBox bgCheckbox;
|
||||
TextView carbs, carbsInsulin;
|
||||
TextView iob, iobInsulin;
|
||||
CheckBox iobCheckbox;
|
||||
TextView correctionInsulin;
|
||||
TextView total, totalInsulin;
|
||||
|
||||
public static final DecimalFormat numberFormat = new DecimalFormat("0.00");
|
||||
public static final DecimalFormat intFormat = new DecimalFormat("0");
|
||||
|
||||
Double calculatedCarbs = 0d;
|
||||
Double calculatedTotalInsulin = 0d;
|
||||
|
||||
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) {
|
||||
calculateInsulin();
|
||||
}
|
||||
};
|
||||
|
||||
final CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
calculateInsulin();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
|
||||
super.onAttach(activity);
|
||||
|
||||
if (activity instanceof Communicator) {
|
||||
communicator = (Communicator) getActivity();
|
||||
|
||||
} else {
|
||||
throw new ClassCastException(activity.toString()
|
||||
+ " must implemenet WizardDialogFragment.Communicator");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.treatments_wizard_fragment, null, false);
|
||||
|
||||
wizardDialogDeliverButton = (Button) view.findViewById(R.id.treatments_wizard_deliverButton);
|
||||
wizardDialogDeliverButton.setOnClickListener(this);
|
||||
|
||||
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
|
||||
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
|
||||
correctionInput = (TextView)view.findViewById(R.id.treatments_wizard_correctioninput);
|
||||
carbsInput = (TextView)view.findViewById(R.id.treatments_wizard_carbsinput);
|
||||
bgInput = (TextView)view.findViewById(R.id.treatments_wizard_bginput);
|
||||
|
||||
correctionInput.addTextChangedListener(textWatcher);
|
||||
carbsInput.addTextChangedListener(textWatcher);
|
||||
bgInput.addTextChangedListener(textWatcher);
|
||||
|
||||
bg = (TextView)view.findViewById(R.id.treatments_wizard_bg);
|
||||
bgInsulin = (TextView)view.findViewById(R.id.treatments_wizard_bginsulin);
|
||||
bgUnits = (TextView)view.findViewById(R.id.treatments_wizard_bgunits);
|
||||
bgCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_bgcheckbox);
|
||||
carbs = (TextView)view.findViewById(R.id.treatments_wizard_carbs);
|
||||
carbsInsulin = (TextView)view.findViewById(R.id.treatments_wizard_carbsinsulin);
|
||||
iob = (TextView)view.findViewById(R.id.treatments_wizard_iob);
|
||||
iobInsulin = (TextView)view.findViewById(R.id.treatments_wizard_iobinsulin);
|
||||
iobCheckbox = (CheckBox) view.findViewById(R.id.treatments_wizard_iobcheckbox);
|
||||
correctionInsulin = (TextView)view.findViewById(R.id.treatments_wizard_correctioninsulin);
|
||||
total = (TextView)view.findViewById(R.id.treatments_wizard_total);
|
||||
totalInsulin = (TextView)view.findViewById(R.id.treatments_wizard_totalinsulin);
|
||||
|
||||
bgCheckbox.setOnCheckedChangeListener(onCheckedChangeListener);
|
||||
iobCheckbox.setOnCheckedChangeListener(onCheckedChangeListener);
|
||||
|
||||
initDialog();
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.treatments_wizard_deliverButton:
|
||||
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d){
|
||||
dismiss();
|
||||
communicator.treatmentDialogDeliver(calculatedTotalInsulin, calculatedCarbs);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void initDialog() {
|
||||
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
String units = SP.getString("ns_units", Constants.MGDL);
|
||||
|
||||
if (MainApp.getNSProfile() == null) {
|
||||
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), "No profile loaded from NS yet");
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
|
||||
bgUnits.setText(units);
|
||||
|
||||
// Set BG if not old
|
||||
BgReading lastBg = MainApp.getDbHelper().lastBg();
|
||||
Double lastBgValue = lastBg.valueToUnits(units);
|
||||
|
||||
if (lastBg != null) {
|
||||
Double sens = MainApp.getNSProfile().getIsf(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double targetBGLow = MainApp.getNSProfile().getTargetLow(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double targetBGHigh = MainApp.getNSProfile().getTargetHigh(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double bgDiff;
|
||||
if (lastBgValue <= targetBGLow) {
|
||||
bgDiff = lastBgValue - targetBGLow;
|
||||
} else {
|
||||
bgDiff = lastBgValue - targetBGHigh;
|
||||
}
|
||||
|
||||
bg.setText(lastBg.valueToUnitsToString(units) + " ISF: " + intFormat.format(sens));
|
||||
bgInsulin.setText(numberFormat.format(bgDiff / sens) + "U");
|
||||
bgInput.setText(lastBg.valueToUnitsToString(units));
|
||||
} else {
|
||||
bg.setText("");
|
||||
bgInsulin.setText("");
|
||||
bgInput.setText("");
|
||||
}
|
||||
|
||||
// IOB calculation
|
||||
MainActivity.treatmentsFragment.updateTotalIOBIfNeeded();
|
||||
MainActivity.tempBasalsFragment.updateTotalIOBIfNeeded();
|
||||
|
||||
Iob bolusIob = MainActivity.treatmentsFragment.lastCalculation;
|
||||
Iob basalIob = MainActivity.tempBasalsFragment.lastCalculation;
|
||||
bolusIob.plus(basalIob);
|
||||
iobInsulin.setText("-" + numberFormat.format(bolusIob.iobContrib) + "U");
|
||||
|
||||
totalInsulin.setText("");
|
||||
wizardDialogDeliverButton.setVisibility(Button.GONE);
|
||||
|
||||
}
|
||||
|
||||
private void calculateInsulin() {
|
||||
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext());
|
||||
Double maxbolus = Double.parseDouble(SP.getString("safety_maxbolus", "3"));
|
||||
Double maxcarbs = Double.parseDouble(SP.getString("safety_maxcarbs", "48"));
|
||||
String units = SP.getString("ns_units", Constants.MGDL);
|
||||
|
||||
NSProfile profile = MainApp.instance().getNSProfile();
|
||||
|
||||
// Entered values
|
||||
String i_bg = this.bgInput.getText().toString();
|
||||
String i_carbs = this.carbsInput.getText().toString();
|
||||
String i_correction = this.correctionInput.getText().toString();
|
||||
Double c_bg = 0d;
|
||||
try { c_bg = Double.parseDouble(i_bg.equals("") ? "0" : i_bg); } catch (Exception e) {}
|
||||
Double c_carbs = 0d;
|
||||
try { c_carbs = Double.parseDouble(i_carbs.equals("") ? "0" : i_carbs); } catch (Exception e) {}
|
||||
c_carbs = ((Long)Math.round(c_carbs)).doubleValue();
|
||||
Double c_correction = 0d;
|
||||
try { c_correction = Double.parseDouble(i_correction.equals("") ? "0" : i_correction); } catch (Exception e) {}
|
||||
if(c_correction > maxbolus) {
|
||||
this.correctionInput.setText("");
|
||||
wizardDialogDeliverButton.setVisibility(Button.GONE);
|
||||
return;
|
||||
}
|
||||
if(c_carbs > maxcarbs) {
|
||||
this.carbsInput.setText("");
|
||||
wizardDialogDeliverButton.setVisibility(Button.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Insulin from BG
|
||||
Double sens = profile.getIsf(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double targetBGLow = profile.getTargetLow(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double targetBGHigh = profile.getTargetHigh(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double bgDiff;
|
||||
if (c_bg <= targetBGLow) {
|
||||
bgDiff = c_bg - targetBGLow;
|
||||
} else {
|
||||
bgDiff = c_bg - targetBGHigh;
|
||||
}
|
||||
Double insulinFromBG = (bgCheckbox.isChecked() && c_bg != 0d) ? bgDiff /sens : 0d;
|
||||
bg.setText(c_bg + " ISF: " + intFormat.format(sens));
|
||||
bgInsulin.setText(numberFormat.format(insulinFromBG) + "U");
|
||||
|
||||
// Insuling from carbs
|
||||
Double ic = profile.getIc(MainApp.getNSProfile().secondsFromMidnight());
|
||||
Double insulinFromCarbs = c_carbs / ic;
|
||||
carbs.setText(intFormat.format(c_carbs) + "g IC: " + intFormat.format(ic));
|
||||
carbsInsulin.setText(numberFormat.format(insulinFromCarbs) + "U");
|
||||
|
||||
// Insulin from IOB
|
||||
MainActivity.treatmentsFragment.updateTotalIOBIfNeeded();
|
||||
MainActivity.tempBasalsFragment.updateTotalIOBIfNeeded();
|
||||
|
||||
Iob bolusIob = MainActivity.treatmentsFragment.lastCalculation;
|
||||
Iob basalIob = MainActivity.tempBasalsFragment.lastCalculation;
|
||||
bolusIob.plus(basalIob);
|
||||
Double insulingFromIOB = iobCheckbox.isChecked() ? bolusIob.iobContrib : 0d;
|
||||
iobInsulin.setText("-" + numberFormat.format(insulingFromIOB) + "U");
|
||||
|
||||
// Insulin from correction
|
||||
Double insulinFromCorrection = c_correction;
|
||||
correctionInsulin.setText(numberFormat.format(insulinFromCorrection) + "U");
|
||||
|
||||
// Total
|
||||
calculatedTotalInsulin = insulinFromBG + insulinFromCarbs - insulingFromIOB + insulinFromCorrection;
|
||||
|
||||
if (calculatedTotalInsulin < 0) {
|
||||
Double carbsEquivalent = -calculatedTotalInsulin * ic;
|
||||
total.setText("Missing " + intFormat.format(carbsEquivalent) + "g");
|
||||
calculatedTotalInsulin = 0d;
|
||||
totalInsulin.setText("");
|
||||
} else {
|
||||
calculatedTotalInsulin = roundTo(calculatedTotalInsulin, 0.05d);
|
||||
total.setText("");
|
||||
totalInsulin.setText(numberFormat.format(calculatedTotalInsulin) + "U");
|
||||
}
|
||||
|
||||
calculatedCarbs = c_carbs;
|
||||
|
||||
if (calculatedTotalInsulin > 0d || calculatedCarbs > 0d) {
|
||||
String insulinText = calculatedTotalInsulin > 0d ? (numberFormat.format(calculatedTotalInsulin) + "U") : "";
|
||||
String carbsText = calculatedCarbs > 0d ? (intFormat.format(calculatedCarbs) + "g") : "";
|
||||
wizardDialogDeliverButton.setText("SEND " + insulinText + " " + carbsText);
|
||||
wizardDialogDeliverButton.setVisibility(Button.VISIBLE);
|
||||
} else {
|
||||
wizardDialogDeliverButton.setVisibility(Button.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private double fromMgdl(Double value, String units) {
|
||||
if (units.equals(Constants.MGDL)) return value;
|
||||
else return value / 18;
|
||||
}
|
||||
|
||||
private Double roundTo(Double x, Double step) {
|
||||
if (x != 0d) {
|
||||
return Math.round(x / step) * step;
|
||||
}
|
||||
return 0d;
|
||||
}
|
||||
|
||||
public interface Communicator {
|
||||
void treatmentDialogDeliver(Double insulin, Double carbs);
|
||||
}
|
||||
|
||||
}
|
|
@ -31,16 +31,17 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import info.nightscout.androidaps.MainActivity;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.events.EventTreatmentChange;
|
||||
import info.nightscout.client.broadcasts.Intents;
|
||||
import info.nightscout.androidaps.plugins.Treatments.Dialogs.NewTreatmentDialogFragment;
|
||||
import info.nightscout.androidaps.Services.Intents;
|
||||
|
||||
public class TreatmentsFragment extends Fragment implements View.OnClickListener {
|
||||
public class TreatmentsFragment extends Fragment implements View.OnClickListener, NewTreatmentDialogFragment.Communicator {
|
||||
private static Logger log = LoggerFactory.getLogger(TreatmentsFragment.class);
|
||||
|
||||
RecyclerView recyclerView;
|
||||
|
@ -50,6 +51,9 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
TextView activityTotal;
|
||||
Button refreshFromNS;
|
||||
|
||||
public long lastCalculationTimestamp = 0;
|
||||
public Iob lastCalculation;
|
||||
|
||||
private static DecimalFormat formatNumber0decimalplaces = new DecimalFormat("0");
|
||||
private static DecimalFormat formatNumber2decimalplaces = new DecimalFormat("0.00");
|
||||
private static DecimalFormat formatNumber3decimalplaces = new DecimalFormat("0.000");
|
||||
|
@ -76,6 +80,15 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
updateTotalIOB();
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalculate IOB if value is older than 1 minute
|
||||
*/
|
||||
public void updateTotalIOBIfNeeded() {
|
||||
if (lastCalculationTimestamp > new Date().getTime() - 60 * 1000)
|
||||
return;
|
||||
updateTotalIOB();
|
||||
}
|
||||
|
||||
private void updateTotalIOB() {
|
||||
Iob total = new Iob();
|
||||
for (Integer pos = 0; pos < treatments.size(); pos++) {
|
||||
|
@ -86,6 +99,9 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
iobTotal.setText(formatNumber2decimalplaces.format(total.iobContrib));
|
||||
if (activityTotal != null)
|
||||
activityTotal.setText(formatNumber3decimalplaces.format(total.activityContrib));
|
||||
|
||||
lastCalculationTimestamp = new Date().getTime();
|
||||
lastCalculation = total;
|
||||
}
|
||||
|
||||
public static class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.TreatmentsViewHolder> {
|
||||
|
@ -233,13 +249,23 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
initializeData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBG ev) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateTotalIOB();
|
||||
recyclerView.getAdapter().notifyDataSetChanged();
|
||||
recyclerView.getAdapter().notifyDataSetChanged(); }
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,7 +273,7 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
super.setUserVisibleHint(isVisibleToUser);
|
||||
|
||||
if (isVisibleToUser)
|
||||
updateTotalIOB();
|
||||
updateTotalIOBIfNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -264,4 +290,10 @@ public class TreatmentsFragment extends Fragment implements View.OnClickListener
|
|||
// TODO: Update argument type and name
|
||||
void onFragmentInteraction(String param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void treatmentDeliverRequest(Double insulin, Double carbs) {
|
||||
// TODO: implement treatment delivery
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
package info.nightscout.androidaps.receivers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.content.WakefulBroadcastReceiver;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.Services.DataService;
|
||||
import info.nightscout.androidaps.tabs.Config;
|
||||
|
||||
|
||||
public class xDripReceiver extends WakefulBroadcastReceiver {
|
||||
private static Logger log = LoggerFactory.getLogger(xDripReceiver.class);
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onReceive " + intent);
|
||||
startWakefulService(context, new Intent(context, DataService.class)
|
||||
.setAction(intent.getAction())
|
||||
.putExtras(intent));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package info.nightscout.androidaps.tabs;
|
||||
|
||||
/**
|
||||
* Created by mike on 07.06.2016.
|
||||
*/
|
||||
public class Config {
|
||||
public static final boolean detailedLog = true;
|
||||
public static final boolean logFunctionCalls = true;
|
||||
public static final boolean logIncommingBG = true;
|
||||
public static final boolean logIncommingData = true;
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
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";
|
||||
String ACTION_RESTART = "info.nightscout.client.RESTART";
|
||||
}
|
|
@ -1,264 +1,24 @@
|
|||
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 android.support.v4.content.WakefulBroadcastReceiver;
|
||||
|
||||
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.Services.DataService;
|
||||
import info.nightscout.androidaps.tabs.Config;
|
||||
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
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 {
|
||||
public class NSClientDataReceiver extends WakefulBroadcastReceiver {
|
||||
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);
|
||||
}
|
||||
}
|
||||
MainApp.bus().post(new EventTreatmentChange());
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (intent.getAction().equals(Intents.ACTION_NEW_SGV)) {
|
||||
MainApp.bus().post(new EventNewBG());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (Config.logFunctionCalls)
|
||||
log.debug("onReceive " + intent);
|
||||
startWakefulService(context, new Intent(context, DataService.class)
|
||||
.setAction(intent.getAction())
|
||||
.putExtras(intent));
|
||||
}
|
||||
}
|
||||
|
|
21
app/src/main/java/info/nightscout/utils/ToastUtils.java
Normal file
21
app/src/main/java/info/nightscout/utils/ToastUtils.java
Normal file
|
@ -0,0 +1,21 @@
|
|||
package info.nightscout.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ToastUtils {
|
||||
|
||||
public static void showToastInUiThread(final Context ctx,
|
||||
final String string) {
|
||||
|
||||
Handler mainThread = new Handler(Looper.getMainLooper());
|
||||
mainThread.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(ctx, string, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
70
app/src/main/res/layout/treatments_newtreatment_fragment.xml
Normal file
70
app/src/main/res/layout/treatments_newtreatment_fragment.xml
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/treatments_newtreatment_insulinamount_label"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text=""
|
||||
android:id="@+id/treatments_newtreatment_insulinamount"
|
||||
android:padding="10dp"
|
||||
android:minWidth="200dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:inputType="numberDecimal"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/treatments_newtreatment_carbsamount_label"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text=""
|
||||
android:id="@+id/treatments_newtreatment_carbsamount"
|
||||
android:padding="10dp"
|
||||
android:minWidth="200dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:inputType="numberDecimal"/>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/treatments_newtreatment_deliverbutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="OK"
|
||||
android:textSize="20sp"
|
||||
android:padding="10dp"
|
||||
android:layout_weight="1"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
332
app/src/main/res/layout/treatments_wizard_fragment.xml
Normal file
332
app/src/main/res/layout/treatments_wizard_fragment.xml
Normal file
|
@ -0,0 +1,332 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="10dp"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/treatments_wizard_bg_label"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:width="80dp" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:id="@+id/treatments_wizard_bginput"
|
||||
android:padding="10dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:inputType="numberDecimal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bgunits"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="mg/dl"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="left"
|
||||
android:paddingLeft="5dp"
|
||||
android:minWidth="40dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/treatments_wizard_carbs_label"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:width="80dp" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text=""
|
||||
android:id="@+id/treatments_wizard_carbsinput"
|
||||
android:padding="10dp"
|
||||
android:minWidth="200dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:inputType="numberDecimal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="g"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="left"
|
||||
android:paddingLeft="5dp"
|
||||
android:minWidth="40dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/treatments_wizard_correction_label"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:width="80dp" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text=""
|
||||
android:id="@+id/treatments_wizard_correctioninput"
|
||||
android:padding="10dp"
|
||||
android:minWidth="200dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:inputType="numberSigned|numberDecimal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_weight="0.5" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/treatments_wizard_unit_label"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="left"
|
||||
android:paddingLeft="5dp"
|
||||
android:minWidth="40dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
android:id="@+id/treatments_wizard_bgcheckbox"
|
||||
android:checked="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/treatments_wizard_bg_label"
|
||||
android:width="50dp"
|
||||
android:id="@+id/textView" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:width="100dp"
|
||||
android:id="@+id/treatments_wizard_bg" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:id="@+id/treatments_wizard_bginsulin"
|
||||
android:width="50dp"
|
||||
android:gravity="end" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/treatments_wizard_carbs_label"
|
||||
android:width="50dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:width="100dp"
|
||||
android:id="@+id/treatments_wizard_carbs" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:id="@+id/treatments_wizard_carbsinsulin"
|
||||
android:width="50dp"
|
||||
android:gravity="end" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
android:id="@+id/treatments_wizard_iobcheckbox"
|
||||
android:checked="true" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/treatments_wizard_iob_label"
|
||||
android:width="50dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:width="100dp"
|
||||
android:id="@+id/treatments_wizard_iob" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:id="@+id/treatments_wizard_iobinsulin"
|
||||
android:width="50dp"
|
||||
android:gravity="end" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="@string/treatments_wizard_correction_label"
|
||||
android:width="50dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:width="100dp"
|
||||
android:id="@+id/treatments_wizard_correction" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:id="@+id/treatments_wizard_correctioninsulin"
|
||||
android:width="50dp"
|
||||
android:gravity="end" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textStyle="bold"
|
||||
android:text="@string/treatments_wizard_total_label"
|
||||
android:width="50dp"
|
||||
android:height="30dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="@color/accent_material_light" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:width="100dp"
|
||||
android:id="@+id/treatments_wizard_total" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textStyle="bold"
|
||||
android:id="@+id/treatments_wizard_totalinsulin"
|
||||
android:width="50dp"
|
||||
android:gravity="center_vertical|end"
|
||||
android:textColor="@color/accent_material_light" />
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_gravity="right">
|
||||
|
||||
<Button
|
||||
android:id="@+id/treatments_wizard_deliverButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="SEND TO PUMP"
|
||||
android:textSize="20sp"
|
||||
android:padding="10dp"
|
||||
android:layout_weight="1"
|
||||
android:textAllCaps="false"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -1,15 +1,9 @@
|
|||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
tools:context=".MainActivity">
|
||||
<item
|
||||
android:id="@+id/nav_home"
|
||||
android:title="@string/nav_home" />
|
||||
<item
|
||||
android:id="@+id/nav_preferences"
|
||||
android:title="@string/nav_preferences" />
|
||||
<item
|
||||
android:id="@+id/nav_refreshtreatments"
|
||||
android:title="@string/nav_refreshtreatments" />
|
||||
<item
|
||||
android:id="@+id/nav_resetdb"
|
||||
android:title="@string/nav_resetdb" />
|
||||
|
|
|
@ -47,5 +47,13 @@
|
|||
<string name="tempbasals_activity_string">Activity:</string>
|
||||
<string name="tempbasals_iobtotal_label_string">Total IOB:</string>
|
||||
<string name="tempbasals_iobactivitytotal_label_string">Total IOB activity:</string>
|
||||
<string name="treatments_newtreatment_insulinamount_label">Insulin amount</string>
|
||||
<string name="treatments_newtreatment_carbsamount_label">Carbs amount</string>
|
||||
<string name="treatments_wizard_bg_label">BG</string>
|
||||
<string name="treatments_wizard_carbs_label">Carbs</string>
|
||||
<string name="treatments_wizard_correction_label">Corr</string>
|
||||
<string name="treatments_wizard_unit_label">U</string>
|
||||
<string name="treatments_wizard_iob_label">IOB</string>
|
||||
<string name="treatments_wizard_total_label">TOTAL</string>
|
||||
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue