First go at adding support for O2 Saturation Data - it expects it to be included in the JSON data string as "O2Sat" in a similar way to heart rate.
This commit is contained in:
Binary file not shown.
@@ -10,8 +10,8 @@
|
|||||||
{
|
{
|
||||||
"type": "SINGLE",
|
"type": "SINGLE",
|
||||||
"filters": [],
|
"filters": [],
|
||||||
"versionCode": 88,
|
"versionCode": 90,
|
||||||
"versionName": "3.6.3a",
|
"versionName": "3.7.0a",
|
||||||
"outputFile": "app-release.apk"
|
"outputFile": "app-release.apk"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
<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"
|
||||||
package="uk.org.openseizuredetector"
|
package="uk.org.openseizuredetector"
|
||||||
android:versionCode="88"
|
android:versionCode="90"
|
||||||
android:versionName="3.6.3a">
|
android:versionName="3.7.0a">
|
||||||
<!-- 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" />
|
||||||
|
|||||||
@@ -460,11 +460,12 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
// Pebble Connected Phrase - use for HR if active instead.
|
// Pebble Connected Phrase - use for HR if active instead.
|
||||||
tv = (TextView) findViewById(R.id.pebbleTv);
|
tv = (TextView) findViewById(R.id.pebbleTv);
|
||||||
if (mConnection.mSdServer.mSdData.mHRAlarmActive) {
|
if (mConnection.mSdServer.mSdData.mHRAlarmActive) {
|
||||||
tv.setText(getString(R.string.HR_Equals) + mConnection.mSdServer.mSdData.mHR);
|
tv.setText(getString(R.string.HR_Equals) + mConnection.mSdServer.mSdData.mHR +" bpm\n"
|
||||||
if (mConnection.mSdServer.mSdData.mHRAlarmStanding) {
|
+ "O2 Sat = " + mConnection.mSdServer.mSdData.mO2Sat + "%");
|
||||||
|
if (mConnection.mSdServer.mSdData.mHRAlarmStanding || mConnection.mSdServer.mSdData.mO2SatAlarmStanding) {
|
||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
tv.setTextColor(alarmTextColour);
|
tv.setTextColor(alarmTextColour);
|
||||||
} else if (mConnection.mSdServer.mSdData.mHRFaultStanding) {
|
} else if (mConnection.mSdServer.mSdData.mHRFaultStanding || mConnection.mSdServer.mSdData.mO2SatFaultStanding) {
|
||||||
tv.setBackgroundColor(warnColour);
|
tv.setBackgroundColor(warnColour);
|
||||||
tv.setTextColor(warnTextColour);
|
tv.setTextColor(warnTextColour);
|
||||||
} else {
|
} else {
|
||||||
@@ -589,7 +590,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
tv.setTextColor(warnTextColour);
|
tv.setTextColor(warnTextColour);
|
||||||
|
|
||||||
tv = (TextView) findViewById(R.id.pebbleTv);
|
tv = (TextView) findViewById(R.id.pebbleTv);
|
||||||
tv.setText(getString(R.string.HR_Equals)+"---");
|
tv.setText(getString(R.string.HR_Equals)+" --- bpm\nO2 Sat = --- %");
|
||||||
tv.setBackgroundColor(warnColour);
|
tv.setBackgroundColor(warnColour);
|
||||||
tv.setTextColor(warnTextColour);
|
tv.setTextColor(warnTextColour);
|
||||||
|
|
||||||
|
|||||||
@@ -65,6 +65,13 @@ public class SdData implements Parcelable {
|
|||||||
public boolean mHRNullAsAlarm = false;
|
public boolean mHRNullAsAlarm = false;
|
||||||
public double mHRThreshMin = 40.0;
|
public double mHRThreshMin = 40.0;
|
||||||
public double mHRThreshMax = 150.0;
|
public double mHRThreshMax = 150.0;
|
||||||
|
|
||||||
|
/* Oxygen Saturation Alarm Settings */
|
||||||
|
public boolean mO2SatAlarmActive = false;
|
||||||
|
public boolean mO2SatNullAsAlarm = false;
|
||||||
|
public double mO2SatThreshMin = 80.0;
|
||||||
|
|
||||||
|
|
||||||
public double rawData[];
|
public double rawData[];
|
||||||
int mNsamp = 0;
|
int mNsamp = 0;
|
||||||
|
|
||||||
@@ -87,6 +94,11 @@ public class SdData implements Parcelable {
|
|||||||
public boolean mHRFaultStanding = false;
|
public boolean mHRFaultStanding = false;
|
||||||
public double mHR = 0;
|
public double mHR = 0;
|
||||||
|
|
||||||
|
public boolean mO2SatAlarmStanding = false;
|
||||||
|
public boolean mO2SatFaultStanding = false;
|
||||||
|
public double mO2Sat = 0;
|
||||||
|
|
||||||
|
|
||||||
public SdData() {
|
public SdData() {
|
||||||
simpleSpec = new int[10];
|
simpleSpec = new int[10];
|
||||||
rawData = new double[N_RAW_DATA];
|
rawData = new double[N_RAW_DATA];
|
||||||
@@ -95,6 +107,7 @@ public class SdData implements Parcelable {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Intialise this SdData object from a JSON String
|
* Intialise this SdData object from a JSON String
|
||||||
|
* FIXME - add O2saturation with checking in case it is not included in the data
|
||||||
*/
|
*/
|
||||||
public boolean fromJSON(String jsonStr) {
|
public boolean fromJSON(String jsonStr) {
|
||||||
Log.v(TAG, "fromJSON() - parsing jsonString - " + jsonStr);
|
Log.v(TAG, "fromJSON() - parsing jsonString - " + jsonStr);
|
||||||
@@ -182,6 +195,10 @@ public class SdData implements Parcelable {
|
|||||||
jsonObj.put("hrThreshMin",mHRThreshMin);
|
jsonObj.put("hrThreshMin",mHRThreshMin);
|
||||||
jsonObj.put("hrThreshMax", mHRThreshMax);
|
jsonObj.put("hrThreshMax", mHRThreshMax);
|
||||||
jsonObj.put("hr",mHR);
|
jsonObj.put("hr",mHR);
|
||||||
|
jsonObj.put("o2SatAlarmActive", mO2SatAlarmActive);
|
||||||
|
jsonObj.put("o2SatAlarmStanding", mO2SatAlarmStanding);
|
||||||
|
jsonObj.put("o2SatThreshMin",mO2SatThreshMin);
|
||||||
|
jsonObj.put("o2Sat",mO2Sat);
|
||||||
JSONArray arr = new JSONArray();
|
JSONArray arr = new JSONArray();
|
||||||
for (int i = 0; i < simpleSpec.length; i++) {
|
for (int i = 0; i < simpleSpec.length; i++) {
|
||||||
arr.put(simpleSpec[i]);
|
arr.put(simpleSpec[i]);
|
||||||
@@ -220,6 +237,7 @@ public class SdData implements Parcelable {
|
|||||||
retval = retval + ", " + mSampleFreq;
|
retval = retval + ", " + mSampleFreq;
|
||||||
retval = retval + ", " + alarmPhrase;
|
retval = retval + ", " + alarmPhrase;
|
||||||
retval = retval + ", " + mHR;
|
retval = retval + ", " + mHR;
|
||||||
|
retval = retval + ", " + mO2Sat;
|
||||||
if (includeRawData) {
|
if (includeRawData) {
|
||||||
for (int i = 0; i< mNsamp;i++) {
|
for (int i = 0; i< mNsamp;i++) {
|
||||||
retval = retval + ", " + rawData[i];
|
retval = retval + ", " + rawData[i];
|
||||||
|
|||||||
@@ -270,6 +270,12 @@ public abstract class SdDataSource {
|
|||||||
// if we get 'null' HR (For example if the heart rate is not working)
|
// if we get 'null' HR (For example if the heart rate is not working)
|
||||||
mSdData.mHR = -1;
|
mSdData.mHR = -1;
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
|
mSdData.mO2Sat = dataObject.getDouble("O2Sat");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
// if we get 'null' O2 Saturation (For example if the oxygen sensor is not working)
|
||||||
|
mSdData.mO2Sat = -1;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
mMute = dataObject.getInt("Mute");
|
mMute = dataObject.getInt("Mute");
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
@@ -455,6 +461,7 @@ public abstract class SdDataSource {
|
|||||||
// Check this data to see if it represents an alarm state.
|
// Check this data to see if it represents an alarm state.
|
||||||
alarmCheck();
|
alarmCheck();
|
||||||
hrCheck();
|
hrCheck();
|
||||||
|
o2SatCheck();
|
||||||
fallCheck();
|
fallCheck();
|
||||||
muteCheck();
|
muteCheck();
|
||||||
Log.v(TAG,"after fallCheck, mSdData.fallAlarmStanding="+mSdData.fallAlarmStanding);
|
Log.v(TAG,"after fallCheck, mSdData.fallAlarmStanding="+mSdData.fallAlarmStanding);
|
||||||
@@ -544,9 +551,39 @@ public abstract class SdDataSource {
|
|||||||
mSdData.mHRAlarmStanding = false;
|
mSdData.mHRAlarmStanding = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hrCheck - check the Heart rate data in mSdData to see if it represents an alarm condition.
|
||||||
|
* Sets mSdData.mHRAlarmStanding
|
||||||
|
*/
|
||||||
|
public void o2SatCheck() {
|
||||||
|
Log.v(TAG, "o2SatCheck()");
|
||||||
|
/* Check Oxygen Saturation against alarm settings */
|
||||||
|
if (mSdData.mO2SatAlarmActive) {
|
||||||
|
if (mSdData.mO2Sat < 0) {
|
||||||
|
if (mSdData.mO2SatNullAsAlarm) {
|
||||||
|
Log.i(TAG, "Oxygen Saturation Null - Alarming");
|
||||||
|
mSdData.mO2SatFaultStanding = false;
|
||||||
|
mSdData.mO2SatAlarmStanding = true;
|
||||||
|
} else {
|
||||||
|
Log.i(TAG, "Oxygen Saturation Fault (O2Sat<0)");
|
||||||
|
mSdData.mO2SatFaultStanding = true;
|
||||||
|
mSdData.mO2SatAlarmStanding = false;
|
||||||
|
}
|
||||||
|
} else if (mSdData.mO2Sat < mSdData.mO2SatThreshMin) {
|
||||||
|
Log.i(TAG, "Oxygen Saturation Abnormal - " + mSdData.mO2Sat + " %");
|
||||||
|
mSdData.mO2SatFaultStanding = false;
|
||||||
|
mSdData.mO2SatAlarmStanding = true;
|
||||||
|
} else {
|
||||||
|
mSdData.mO2SatFaultStanding = false;
|
||||||
|
mSdData.mO2SatAlarmStanding = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************
|
/****************************************************************
|
||||||
* Simple threshold analysis to chech for fall.
|
* Simple threshold analysis to chech for fall.
|
||||||
* Called from clock_tick_handler()
|
* Called from clock_tick_handler()
|
||||||
@@ -816,6 +853,19 @@ public abstract class SdDataSource {
|
|||||||
Log.v(TAG, "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
|
Log.v(TAG, "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
|
||||||
mUtil.writeToSysLogFile( "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
|
mUtil.writeToSysLogFile( "updatePrefs() HRThreshMax = " + mSdData.mHRThreshMax);
|
||||||
|
|
||||||
|
mSdData.mO2SatAlarmActive = SP.getBoolean("O2SatAlarmActive", false);
|
||||||
|
Log.v(TAG, "updatePrefs() O2SatAlarmActive = " + mSdData.mO2SatAlarmActive);
|
||||||
|
mUtil.writeToSysLogFile( "updatePrefs() O2SatAlarmActive = " + mSdData.mO2SatAlarmActive);
|
||||||
|
|
||||||
|
mSdData.mO2SatNullAsAlarm = SP.getBoolean("O2SatNullAsAlarm", false);
|
||||||
|
Log.v(TAG, "updatePrefs() O2SatNullAsAlarm = " + mSdData.mO2SatNullAsAlarm);
|
||||||
|
mUtil.writeToSysLogFile( "updatePrefs() O2SatNullAsAlarm = " + mSdData.mO2SatNullAsAlarm);
|
||||||
|
|
||||||
|
prefStr = SP.getString("O2SatThreshMin", "SET_FROM_XML");
|
||||||
|
mSdData.mO2SatThreshMin = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() O2SatThreshMin = " + mSdData.mO2SatThreshMin);
|
||||||
|
mUtil.writeToSysLogFile( "updatePrefs() O2SatThreshMin = " + mSdData.mO2SatThreshMin);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "updatePrefs() - prefStr is null - WHY????");
|
Log.v(TAG, "updatePrefs() - prefStr is null - WHY????");
|
||||||
mUtil.writeToSysLogFile("SDDataSource.updatePrefs() - prefStr is null - WHY??");
|
mUtil.writeToSysLogFile("SDDataSource.updatePrefs() - prefStr is null - WHY??");
|
||||||
|
|||||||
@@ -672,9 +672,43 @@ public class SdServer extends Service implements SdDataReceiver {
|
|||||||
mUtil.showToast(getString(R.string.SMSAlarmDisabledNotSendingMsg));
|
mUtil.showToast(getString(R.string.SMSAlarmDisabledNotSendingMsg));
|
||||||
Log.v(TAG, "mSMSAlarm is false - not sending");
|
Log.v(TAG, "mSMSAlarm is false - not sending");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle Oxygen Saturation alarm
|
||||||
|
if ((sdData.mO2SatAlarmActive) && (sdData.mO2SatAlarmStanding)) {
|
||||||
|
sdData.alarmPhrase = "Oxygen Saturation ABNORMAL";
|
||||||
|
if (mLogAlarms) {
|
||||||
|
Log.v(TAG, "***OXYGEN SATURATION*** - Logging to SD Card");
|
||||||
|
writeAlarmToSD();
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "***OXYGEN SATURATION***");
|
||||||
|
}
|
||||||
|
// Make alarm beep tone
|
||||||
|
alarmBeep();
|
||||||
|
showNotification(2);
|
||||||
|
// Display MainActvity
|
||||||
|
showMainActivity();
|
||||||
|
// Send SMS Alarm.
|
||||||
|
if (mSMSAlarm) {
|
||||||
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
|
tnow.setToNow();
|
||||||
|
// limit SMS alarms to one per minute
|
||||||
|
if ((tnow.toMillis(false)
|
||||||
|
- mSMSTime.toMillis(false))
|
||||||
|
> 60000) {
|
||||||
|
sendSMSAlarm();
|
||||||
|
mSMSTime = tnow;
|
||||||
|
} else {
|
||||||
|
mUtil.showToast("SMS Alarm already sent - not re-sending");
|
||||||
|
Log.v(TAG, "SMS Alarm already sent - not re-sending");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mUtil.showToast(getString(R.string.SMSAlarmDisabledNotSendingMsg));
|
||||||
|
Log.v(TAG, "mSMSAlarm is false - not sending");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Fault
|
// Fault
|
||||||
if ((sdData.alarmState) == 4 || (sdData.alarmState == 7) || (sdData.mHRFaultStanding)) {
|
if ((sdData.alarmState) == 4 || (sdData.alarmState == 7) || (sdData.mHRFaultStanding)) {
|
||||||
sdData.alarmPhrase = "FAULT";
|
sdData.alarmPhrase = "FAULT";
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">OpenSeizureDetector</string>
|
<string name="app_name">OpenSeizureDetector</string>
|
||||||
<string name="changelog">
|
<string name="changelog">
|
||||||
"V3.6.2 - Fix of issue with log file permissions on some Android 10 devices and added more translatable strings with polish translation.
|
"V3.7.0 - Added support for Garmin Blood Oxygen Saturation measurements
|
||||||
|
\nV3.6.2 - Fix of issue with log file permissions on some Android 10 devices and added more translatable strings with polish translation.
|
||||||
\nV3.6.1 - Possible fix for issue with shutting down system and expanded Polish translation to all settings screens.
|
\nV3.6.1 - Possible fix for issue with shutting down system and expanded Polish translation to all settings screens.
|
||||||
\nV3.6 - Added phone sensor data source for testing without a watches
|
\nV3.6 - Added phone sensor data source for testing without a watches
|
||||||
\nV3.5 - Added support for SMS Annunciator App
|
\nV3.5 - Added support for SMS Annunciator App
|
||||||
@@ -282,4 +283,11 @@
|
|||||||
<string name="WarnTimeTitle">WarnTime (sec)</string>
|
<string name="WarnTimeTitle">WarnTime (sec)</string>
|
||||||
<string name="AlarmTimeSummary">Time to wait before initiating alarm (Default = 10 sec)</string>
|
<string name="AlarmTimeSummary">Time to wait before initiating alarm (Default = 10 sec)</string>
|
||||||
<string name="AlarmTimeTitle">AlarmTime (sec)</string>
|
<string name="AlarmTimeTitle">AlarmTime (sec)</string>
|
||||||
|
<string name="O2SatSettingsTitle">Blood Oxygen Saturation Alarm Settigs</string>
|
||||||
|
<string name="O2Sat_enabled_summary">O2Sat_enabled_summary</string>
|
||||||
|
<string name="O2Sat_enabled_title">Enable O2 Saturation Alarm</string>
|
||||||
|
<string name="O2SatNullAlarmSummary">Treat an error condition (null value of oxygen saturation reading) as an alarm condition</string>
|
||||||
|
<string name="O2SatNullAlarmTitle">Treat Null Value as Alarm</string>
|
||||||
|
<string name="O2SatThreshMinTitle">Oxygen Saturation Low Alarm Level (%)</string>
|
||||||
|
<string name="O2SatThreshMinSummary">O2 Saturation Low Alarm Level (%)</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -65,6 +65,24 @@
|
|||||||
android:title="@string/HRThreshMaxTitle" />
|
android:title="@string/HRThreshMaxTitle" />
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="@string/O2SatSettingsTitle">
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="O2SatAlarmActive"
|
||||||
|
android:summary="@string/O2Sat_enabled_summary"
|
||||||
|
android:title="@string/O2Sat_enabled_title" />
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="O2SatNullAsAlarm"
|
||||||
|
android:summary="@string/O2SatNullAlarmSummary"
|
||||||
|
android:title="@string/O2SatNullAlarmTitle" />
|
||||||
|
<EditTextPreference
|
||||||
|
android:defaultValue="80"
|
||||||
|
android:key="O2SatThreshMin"
|
||||||
|
android:summary="@string/O2SatThreshMinSummary"
|
||||||
|
android:title="@string/O2SatThreshMinTitle" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory android:title="@string/fall_detect_title">
|
<PreferenceCategory android:title="@string/fall_detect_title">
|
||||||
<CheckBoxPreference
|
<CheckBoxPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|||||||
Reference in New Issue
Block a user