Partial merge of the HR history graphs by @AroonPro - still need to add averaging option and then make the x scale user selectable - it is 3 hours at the moment

This commit is contained in:
Graham Jones
2024-01-13 13:42:38 +00:00
parent 9bfcc01525
commit f81a6e7dde
5 changed files with 136 additions and 13 deletions

View File

@@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:versionCode="128" android:versionCode="128"
android:versionName="4.2.1j"> android:versionName="4.2.1k">
<!-- android:allowBackup="false" --> <!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

View File

@@ -1,5 +1,6 @@
package uk.org.openseizuredetector; package uk.org.openseizuredetector;
import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
@@ -7,8 +8,39 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.widget.SwitchCompat;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.utils.ColorTemplate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
public class FragmentHrAlg extends FragmentOsdBaseClass { public class FragmentHrAlg extends FragmentOsdBaseClass {
String TAG = "FragmentOsdAlg"; String TAG = "FragmentOsdAlg";
LineChart lineChart;
LineData lineData;
LineDataSet lineDataSet;
List<Entry> hrHistory = new ArrayList<>();
List<Entry> hrAverages = new ArrayList<>();
List<String> hrHistoryStrings = new ArrayList<>();
List<String> hrAveragesStrings = new ArrayList<>();
private List<Entry> listToDisplay;
private List<String> listToDisplayStrings;
private TextView tvAvgAHr;
private TextView tvHr;
private TextView tv;
private TextView tvCurrent;
private SwitchCompat switchAverages;
public FragmentHrAlg() { public FragmentHrAlg() {
// Required empty public constructor // Required empty public constructor
} }
@@ -17,6 +49,16 @@ public class FragmentHrAlg extends FragmentOsdBaseClass {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
lineDataSet = new LineDataSet(new ArrayList<Entry>(),"Heart rate history" );
lineDataSet.setColors(ColorTemplate.JOYFUL_COLORS);
lineDataSet.setValueTextColor(Color.BLACK);
lineDataSet.setValueTextSize(18f);
lineDataSet.setDrawValues(false);
//lineDataSetAverage = new LineDataSet(new ArrayList<Entry>(),"Heart rate history" );
//lineDataSetAverage.setColors(ColorTemplate.JOYFUL_COLORS);
//lineDataSetAverage.setValueTextColor(Color.BLACK);
//lineDataSetAverage.setValueTextSize(18f);
} }
@Override @Override
@@ -28,16 +70,66 @@ public class FragmentHrAlg extends FragmentOsdBaseClass {
@Override @Override
protected void updateUi() { protected void updateUi() {
Log.d(TAG,"updateUi()"); Log.d(TAG, "updateUi()");
TextView tv; tv = (TextView) mRootView.findViewById(R.id.fragment_hr_alg_tv1);
tv = (TextView)mRootView.findViewById(R.id.fragment_hr_alg_tv1); tvHr = (TextView) mRootView.findViewById(R.id.current_hr_tv);
tvAvgAHr = (TextView) mRootView.findViewById(R.id.adaptive_avg_hr_tv);
if (mConnection.mBound) { if (mConnection.mBound) {
tv.setText("Bound to Server"); tv.setText("Bound to Server");
tvCurrent = mRootView.findViewById(R.id.textView2);
if (Objects.nonNull(tvCurrent)) {
if (Objects.nonNull(tvHr))
tvHr.setText( String.valueOf((short)mConnection.mSdServer.mSdData.mHR));
if (Objects.nonNull(tvAvgAHr))
tvAvgAHr.setText( String.valueOf((short)mConnection.mSdServer.mSdData
.mAdaptiveHrAverage));
tvCurrent.setText(new StringBuilder()
.append(mConnection.mSdServer.mSdData.mAdaptiveHrAverage)
.append("\nResult of checks: Adaptive Hr Alarm Standing: ")
.append(mConnection.mSdServer.mSdData.mAdaptiveHrAlarmStanding)
.append("\nAverage Hr Alarm Standing: ")
.append(mConnection.mSdServer.mSdData.mAdaptiveHrAlarmStanding)
.toString());
switchAverages = mRootView.findViewById(R.id.hr_average_switch);
if (Objects.nonNull(mConnection.mSdServer.mSdDataSource.mSdAlgHr)) {
Log.v(TAG,"mSdAlgHr si not null");
CircBuf hrHist = mConnection.mSdServer.mSdDataSource.mSdAlgHr.getHrHistBuff();
int nHistArr = hrHist.getNumVals();
double hrHistArr[] = hrHist.getVals(); // This gives us a simple vector of hr values to plot.
if (Objects.nonNull(hrHist) && nHistArr > 0) {
Log.v(TAG, "hrHist.getNumVals="+nHistArr);
lineDataSet.clear();
String xVals[] = new String[nHistArr];
for (int i = 0; i<nHistArr; i++) {
Log.d(TAG,"i="+i+", HR="+hrHistArr[i]);
xVals[i] = String.valueOf(i);
lineDataSet.addEntry(new Entry((float)hrHistArr[i], i));
}
Log.d(TAG,"xVals="+ Arrays.toString(xVals)+ ", lneDataSet="+lineDataSet.toSimpleString());
LineData hrHistLineData = new LineData(xVals, lineDataSet);
lineChart = mRootView.findViewById(R.id.lineChart);
lineChart.setData(hrHistLineData);
lineChart.getData().notifyDataChanged();
lineChart.notifyDataSetChanged();
lineChart.refreshDrawableState();
lineChart.invalidate();
//if (mConnection.mBound){
// lineChart.postInvalidate();
//}
}
}
} else { } else {
tv.setText("****NOT BOUND TO SERVER***"); tv.setText("****NOT BOUND TO SERVER***");
return; return;
} }
}
} }
} }

View File

@@ -27,6 +27,7 @@ public class SdAlgHr {
private CircBuf mAdaptiveHrBuff; private CircBuf mAdaptiveHrBuff;
private CircBuf mAverageHrBuff; private CircBuf mAverageHrBuff;
private CircBuf mHrHist;
public SdAlgHr(Context context) { public SdAlgHr(Context context) {
Log.i(TAG, "SdAlgHr Constructor"); Log.i(TAG, "SdAlgHr Constructor");
@@ -34,6 +35,8 @@ public class SdAlgHr {
updatePrefs(); updatePrefs();
mAdaptiveHrBuff = new CircBuf(mAdaptiveHrAlarmWindowDp, -1.0); mAdaptiveHrBuff = new CircBuf(mAdaptiveHrAlarmWindowDp, -1.0);
mAverageHrBuff = new CircBuf(mAverageHrAlarmWindowDp, -1.0); mAverageHrBuff = new CircBuf(mAverageHrAlarmWindowDp, -1.0);
// FIXME - this is a hard coded 3 hour period (at 5 second intervals)
mHrHist = new CircBuf((int)(3 * 3600 / 5), -1);
} }
public void close() { public void close() {
@@ -127,6 +130,8 @@ public class SdAlgHr {
return mAdaptiveHrBuff; return mAdaptiveHrBuff;
} }
public CircBuf getHrHistBuff() { return mHrHist; }
/** /**
* Returns the average heart rate being used by the Average heart rate algorithm * Returns the average heart rate being used by the Average heart rate algorithm
* @return Average Heart rate in bpm. * @return Average Heart rate in bpm.
@@ -183,6 +188,7 @@ public class SdAlgHr {
Log.v(TAG, "checkHr("+hrVal+")"); Log.v(TAG, "checkHr("+hrVal+")");
mAdaptiveHrBuff.add(hrVal); mAdaptiveHrBuff.add(hrVal);
mAverageHrBuff.add(hrVal); mAverageHrBuff.add(hrVal);
mHrHist.add(hrVal);
ArrayList<Boolean> retVal = new ArrayList<Boolean>(); ArrayList<Boolean> retVal = new ArrayList<Boolean>();
retVal.add(checkSimpleHr(hrVal)); retVal.add(checkSimpleHr(hrVal));
retVal.add(checkAdaptiveHr(hrVal)); retVal.add(checkAdaptiveHr(hrVal));

View File

@@ -95,7 +95,7 @@ public abstract class SdDataSource {
private short mFallWindow; private short mFallWindow;
private int mMute; // !=0 means muted by keypress on watch. private int mMute; // !=0 means muted by keypress on watch.
private SdAlgNn mSdAlgNn; private SdAlgNn mSdAlgNn;
private SdAlgHr mSdAlgHr; protected SdAlgHr mSdAlgHr;
// Values for SD_MODE // Values for SD_MODE
private int SIMPLE_SPEC_FMAX = 10; private int SIMPLE_SPEC_FMAX = 10;

View File

@@ -5,13 +5,15 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".FragmentOsdBaseClass"> tools:context=".FragmentOsdBaseClass">
<!-- TODO: Update blank fragment layout -->
<androidx.appcompat.widget.LinearLayoutCompat <androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="253dp" android:layout_height="match_parent"
android:background="@color/okBackgroundColor" android:background="@color/okBackgroundColor"
android:orientation="vertical"> android:orientation="vertical">
<!-- TODO: Update blank fragment layout -->
<TextView <TextView
android:id="@+id/fragment_hr_alg_tv1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="HR Algorithm Status" android:text="HR Algorithm Status"
@@ -68,11 +70,34 @@
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>
<TextView <TextView
android:id="@+id/fragment_hr_alg_tv1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Fragment_HrAlg" /> android:text="Fragment_HrAlg" />
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/hr_average_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show averages" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
</com.github.mikephil.charting.charts.LineChart>
</FrameLayout>
</androidx.appcompat.widget.LinearLayoutCompat> </androidx.appcompat.widget.LinearLayoutCompat>