Added adaptive and average heart rate data to SdData so that it is logged to the data sharing database.

This commit is contained in:
Graham Jones
2023-06-16 21:56:36 +01:00
parent 968f1bf883
commit 3e61397eb5
9 changed files with 130 additions and 23 deletions

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:versionCode="121"
android:versionName="4.1.7">
android:versionCode="122"
android:versionName="4.1.8">
<!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

View File

@@ -651,10 +651,16 @@ public class MainActivity extends AppCompatActivity {
tv = (TextView) findViewById(R.id.pebbleTv);
//if (mConnection.mSdServer.mSdData.mHRAlarmActive) {
if (mConnection.mSdServer.mSdData.mO2Sat > 0) {
tv.setText(getString(R.string.HR_Equals) + mConnection.mSdServer.mSdData.mHR + " bpm\n"
+ getString(R.string.SpO2)+" = " + mConnection.mSdServer.mSdData.mO2Sat + "%");
tv.setText(getString(R.string.HR_Equals) + Math.round(mConnection.mSdServer.mSdData.mHR) + " bpm\n"
+"(av="
+Math.round(mConnection.mSdServer.mSdData.mAdaptiveHrAverage)+","
+Math.round(mConnection.mSdServer.mSdData.mAverageHrAverage)+") bpm\n"
+ getString(R.string.SpO2)+" = " + Math.round(mConnection.mSdServer.mSdData.mO2Sat) + "%");
} else {
tv.setText(getString(R.string.HR_Equals) + mConnection.mSdServer.mSdData.mHR + " bpm\n"
tv.setText(getString(R.string.HR_Equals) + Math.round(mConnection.mSdServer.mSdData.mHR) + " bpm\n"
+"(av="
+Math.round(mConnection.mSdServer.mSdData.mAdaptiveHrAverage)+","
+Math.round(mConnection.mSdServer.mSdData.mAverageHrAverage)+") bpm\n"
+ getString(R.string.SpO2)+" = ---%");
}
if (mConnection.mSdServer.mSdData.mHRAlarmStanding || mConnection.mSdServer.mSdData.mO2SatAlarmStanding) {

View File

@@ -111,11 +111,36 @@ public class SdAlgHr {
return(retVal);
}
/**
* Returns the average heart rate being used by the Adaptive heart rate algorithm
* @return Average Heart reate in bpm.
*/
public double getAdaptiveHrAverage() {
return mAdaptiveHrBuff.getAverageVal();
}
public CircBuf getAverageHrBuff() {
return mAverageHrBuff;
}
public CircBuf getAdaptiveHrBuff() {
return mAdaptiveHrBuff;
}
/**
* Returns the average heart rate being used by the Average heart rate algorithm
* @return Average Heart rate in bpm.
*/
public double getAverageHrAverage() {
return mAverageHrBuff.getAverageVal();
}
private boolean checkAdaptiveHr(double hrVal) {
boolean retVal;
double hrThreshMin;
double hrThreshMax;
double avHr = mAdaptiveHrBuff.getAverageVal();
double avHr = getAdaptiveHrAverage();
hrThreshMin = avHr - mAdaptiveHrAlarmThresh;
hrThreshMax = avHr + mAdaptiveHrAlarmThresh;
@@ -133,7 +158,7 @@ public class SdAlgHr {
private boolean checkAverageHr(double hrVal) {
boolean retVal;
double avHr = mAdaptiveHrBuff.getAverageVal();
double avHr = getAverageHrAverage();
retVal = false;
if (hrVal < mAverageHrAlarmThreshMin) {

View File

@@ -87,6 +87,18 @@ public class SdData implements Parcelable {
public double rawData[];
public double rawData3D[];
public boolean mAdaptiveHrAlarmActive;
public double mAdaptiveHrAlarmWindowSecs;
public double mAdaptiveHrAlarmThresh;
public boolean mAverageHrAlarmActive;
public double mAverageHrAlarmWindowSecs;
public double mAverageHrAlarmThreshMin;
public double mAverageHrAlarmThreshMax;
public double mAverageHrAverage;
public double mAdaptiveHrAverage;
public CircBuf mAdaptiveHrBuf;
public CircBuf mAverageHrBuf;
int mNsamp = 0;
/* Analysis results */
@@ -106,8 +118,8 @@ public class SdData implements Parcelable {
public boolean mHRAlarmStanding = false;
public boolean mHRFaultStanding = false;
public boolean mAdaptiveHRAlarmStanding = false;
public boolean mAverageHRAlarmStanding = false;
public boolean mAdaptiveHrAlarmStanding = false;
public boolean mAverageHrAlarmStanding = false;
public double mHR = 0;
public boolean mO2SatAlarmStanding = false;
@@ -210,6 +222,8 @@ public class SdData implements Parcelable {
jsonObj.put("alarmState", alarmState);
jsonObj.put("alarmPhrase", alarmPhrase);
jsonObj.put("hr", mHR);
jsonObj.put("adaptiveHrAv", mAdaptiveHrAverage);
jsonObj.put("averageHrAv", mAverageHrAverage);
jsonObj.put("o2Sat", mO2Sat);
jsonObj.put("pSeizure", mPseizure);
JSONArray arr = new JSONArray();
@@ -269,6 +283,15 @@ public class SdData implements Parcelable {
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
jsonObj.put("hrThreshMin", mHRThreshMin);
jsonObj.put("hrThreshMax", mHRThreshMax);
jsonObj.put("adaptiveHrAlarmActive", mAdaptiveHrAlarmActive);
jsonObj.put("adaptiveHrAlarmStanding", mAdaptiveHrAlarmStanding);
jsonObj.put("adaptiveHrAlarmWindow", mAdaptiveHrAlarmWindowSecs);
jsonObj.put("adaptiveHrAlarmThresh", mAdaptiveHrAlarmThresh);
jsonObj.put("averageHrAlarmActive", mAverageHrAlarmActive);
jsonObj.put("averageHrAlarmStanding", mAverageHrAlarmStanding);
jsonObj.put("averageHrAlarmThreshMin", mAverageHrAlarmThreshMin);
jsonObj.put("averageHrAlarmThreshMax", mAverageHrAlarmThreshMax);
jsonObj.put("o2SatAlarmActive", mO2SatAlarmActive);
jsonObj.put("o2SatAlarmStanding", mO2SatAlarmStanding);
jsonObj.put("o2SatThreshMin", mO2SatThreshMin);
@@ -320,12 +343,14 @@ public class SdData implements Parcelable {
jsonObj.put("alarmRatioThresh", alarmRatioThresh);
jsonObj.put("hrAlarmActive", mHRAlarmActive);
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
jsonObj.put("adaptiveHrAlarmStanding", mAdaptiveHRAlarmStanding);
jsonObj.put("averageHrAlarmStanding", mAverageHRAlarmStanding);
jsonObj.put("adaptiveHrAlarmStanding", mAdaptiveHrAlarmStanding);
jsonObj.put("averageHrAlarmStanding", mAverageHrAlarmStanding);
jsonObj.put("hrAlarmStanding", mHRAlarmStanding);
jsonObj.put("hrThreshMin", mHRThreshMin);
jsonObj.put("hrThreshMax", mHRThreshMax);
jsonObj.put("hr", mHR);
jsonObj.put("adaptiveHrAv", mAdaptiveHrAverage);
jsonObj.put("averageHrAv", mAverageHrAverage);
jsonObj.put("o2SatAlarmActive", mO2SatAlarmActive);
jsonObj.put("o2SatAlarmStanding", mO2SatAlarmStanding);
jsonObj.put("o2SatThreshMin", mO2SatThreshMin);

View File

@@ -592,6 +592,13 @@ public abstract class SdDataSource {
Log.v(TAG, "hrCheck()");
ArrayList<Boolean> checkResults;
checkResults = mSdAlgHr.checkHr(mSdData.mHR);
// Populate mSdData so that the heart rate data is logged and is accessible to user interface components.
mSdData.mAdaptiveHrAverage = mSdAlgHr.getAdaptiveHrAverage();
mSdData.mAverageHrAverage = mSdAlgHr.getAverageHrAverage();
mSdData.mAdaptiveHrBuf = mSdAlgHr.getAdaptiveHrBuff();
mSdData.mAverageHrBuf = mSdAlgHr.getAverageHrBuff();
/* Check for heart rate fault condition */
if (mSdData.mHRAlarmActive) {
if (mSdData.mHR < 0) {
@@ -599,30 +606,30 @@ public abstract class SdDataSource {
Log.i(TAG, "Heart Rate Null - Alarming");
mSdData.mHRFaultStanding = false;
mSdData.mHRAlarmStanding = true;
mSdData.mAdaptiveHRAlarmStanding = false;
mSdData.mAverageHRAlarmStanding = false;
mSdData.mAdaptiveHrAlarmStanding = false;
mSdData.mAverageHrAlarmStanding = false;
} else {
Log.i(TAG, "Heart Rate Fault (HR<0)");
mSdData.mHRFaultStanding = true;
mSdData.mHRAlarmStanding = false;
mSdData.mAdaptiveHRAlarmStanding = false;
mSdData.mAverageHRAlarmStanding = false;
mSdData.mAdaptiveHrAlarmStanding = false;
mSdData.mAverageHrAlarmStanding = false;
}
} else {
mSdData.mHRFaultStanding = false;
mSdData.mHRAlarmStanding = checkResults.get(0);
mSdData.mAdaptiveHRAlarmStanding = checkResults.get(1);
mSdData.mAverageHRAlarmStanding = checkResults.get(2);
mSdData.mAdaptiveHrAlarmStanding = checkResults.get(1);
mSdData.mAverageHrAlarmStanding = checkResults.get(2);
// Show an ALARM state if any of the HR alarms is standing.
if (mSdData.mHRAlarmStanding | mSdData.mAdaptiveHRAlarmStanding | mSdData.mAverageHRAlarmStanding) {
if (mSdData.mHRAlarmStanding | mSdData.mAdaptiveHrAlarmStanding | mSdData.mAverageHrAlarmStanding) {
mSdData.alarmState = 2;
}
}
} else {
mSdData.mHRFaultStanding = false;
mSdData.mHRAlarmStanding = false;
mSdData.mAdaptiveHRAlarmStanding = false;
mSdData.mAverageHRAlarmStanding = false;
mSdData.mAdaptiveHrAlarmStanding = false;
mSdData.mAverageHrAlarmStanding = false;
}
}
@@ -787,6 +794,28 @@ public abstract class SdDataSource {
}
}
/**
* Read a preference value, and return it as a double.
* FIXME - this should be in osdUtil so other classes can use it.
*
* @param SP - Shared Preferences object
* @param prefName - name of preference to read.
* @param defVal - default value if it is not stored.
* @return double value of the stored specified preference, or the default value.
*/
private double readDoublePref(SharedPreferences SP, String prefName, String defVal) {
String prefValStr;
double retVal = -1;
try {
prefValStr = SP.getString(prefName, defVal);
retVal = Double.parseDouble(prefValStr);
} catch (Exception ex) {
Log.v(TAG, "readDoublePref() - Problem with preference!");
//mUtil.showToast(TAG+":"+mContext.getString(R.string.problem_parsing_preferences));
}
return retVal;
}
/**
* updatePrefs() - update basic settings from the SharedPreferences
* - defined in res/xml/SdDataSourceNetworkPassivePrefs.xml
@@ -952,6 +981,23 @@ public abstract class SdDataSource {
Log.v(TAG, "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
mUtil.writeToSysLogFile( "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
mSdData.mAdaptiveHrAlarmActive = SP.getBoolean("HRAdaptiveAlarmActive", false);
mSdData.mAdaptiveHrAlarmWindowSecs = readDoublePref(SP, "HRAdaptiveAlarmWindowSecs", "30");
mSdData.mAdaptiveHrAlarmThresh = readDoublePref(SP, "HRAdaptiveAlarmThresh", "20");
Log.d(TAG,"updatePrefs(): mAdaptiveHrAlarmActive="+mSdData.mAdaptiveHrAlarmActive);
Log.d(TAG,"updatePrefs(): mAdaptiveHrWindowSecs="+mSdData.mAdaptiveHrAlarmWindowSecs);
Log.d(TAG,"updatePrefs(): mAdaptiveHrAlarmThresh="+mSdData.mAdaptiveHrAlarmThresh);
mSdData.mAverageHrAlarmActive = SP.getBoolean("HRAverageAlarmActive", false);
mSdData.mAverageHrAlarmWindowSecs = readDoublePref(SP, "HRAverageAlarmWindowSecs", "120");
mSdData.mAverageHrAlarmThreshMin = readDoublePref(SP, "HRAverageAlarmThreshMin", "40");
mSdData.mAverageHrAlarmThreshMax = readDoublePref(SP, "HRAverageAlarmThreshMax", "120");
Log.d(TAG,"updatePrefs(): mAverageHrAlarmActive="+mSdData.mAverageHrAlarmActive);
Log.d(TAG,"updatePrefs(): mAverageHrAlarmWindowSecs="+mSdData.mAverageHrAlarmWindowSecs);
Log.d(TAG,"updatePrefs(): mAverageHrAlarmThreshMin="+mSdData.mAverageHrAlarmThreshMin);
Log.d(TAG,"updatePrefs(): mAverageHrAlarmThreshMax="+mSdData.mAverageHrAlarmThreshMax);
mSdData.mO2SatAlarmActive = SP.getBoolean("O2SatAlarmActive", false);
Log.v(TAG, "updatePrefs() O2SatAlarmActive = " + mSdData.mO2SatAlarmActive);
mUtil.writeToSysLogFile( "updatePrefs() O2SatAlarmActive = " + mSdData.mO2SatAlarmActive);

View File

@@ -128,7 +128,7 @@ public class SdWebServer extends NanoHTTPD {
case GET:
//Log.v(TAG,"WebServer.serve() - Returning settings");
try {
JSONObject jsonObj = new JSONObject();
/*JSONObject jsonObj = new JSONObject();
jsonObj.put("alarmFreqMin", mSdData.alarmFreqMin);
jsonObj.put("alarmFreqMax", mSdData.alarmFreqMax);
jsonObj.put("nMin", mSdData.nMin);
@@ -139,6 +139,8 @@ public class SdWebServer extends NanoHTTPD {
jsonObj.put("alarmRatioThresh", mSdData.alarmRatioThresh);
jsonObj.put("batteryPc", mSdData.batteryPc);
answer = jsonObj.toString();
*/
answer = mSdData.toSettingsJSON();
} catch (Exception ex) {
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
answer = "{'msg': 'Error Creating Data Object'}";

View File

@@ -10,7 +10,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath 'com.android.tools.build:gradle:8.0.2'
classpath 'com.google.gms:google-services:4.3.15'
}
}

View File

@@ -14,3 +14,6 @@
org.gradle.jvmargs=-Xmx1536M -Dkotlin.daemon.jvm.options\="-Xmx1536M"
android.enableJetifier=true
android.useAndroidX=true
android.defaults.buildfeatures.buildconfig=true
android.nonTransitiveRClass=false
android.nonFinalResIds=false

View File

@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip