V2.6.0 - Added support for early Garmin based seizure detector (v0.1 of Garmin SD watch app). Uses Send_sms permission still.

This commit is contained in:
Graham Jones
2019-01-20 21:29:41 +00:00
parent 8f823aaa57
commit 5e17623586
17 changed files with 366 additions and 182 deletions

Binary file not shown.

View File

@@ -9,7 +9,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--<uses-permission android:name="android.permission.SEND_SMS" />-->
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

View File

@@ -413,17 +413,28 @@ public class MainActivity extends AppCompatActivity {
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
// Pebble Connected Phrase
// Pebble Connected Phrase - use for HR if active instead.
tv = (TextView) findViewById(R.id.pebbleTv);
if (mConnection.mSdServer.mSdData.pebbleConnected) {
tv.setText("Watch Connected OK");
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
if (mConnection.mSdServer.mSdData.mHRAlarmActive) {
tv.setText("HR = "+mConnection.mSdServer.mSdData.mHR);
if (!mConnection.mSdServer.mSdData.mHRAlarmStanding) {
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
} else {
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
} else {
tv.setText("Watch NOT Connected");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
if (mConnection.mSdServer.mSdData.pebbleConnected) {
tv.setText("Watch Connected OK");
tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour);
} else {
tv.setText("Watch NOT Connected");
tv.setBackgroundColor(warnColour);
tv.setTextColor(warnTextColour);
}
}
tv = (TextView) findViewById(R.id.appTv);
if (mConnection.mSdServer.mSdData.pebbleAppRunning) {
@@ -436,7 +447,7 @@ public class MainActivity extends AppCompatActivity {
tv.setTextColor(warnTextColour);
}
tv = (TextView) findViewById(R.id.battTv);
tv.setText("Pebble Battery = " + String.valueOf(mConnection.mSdServer.mSdData.batteryPc) + "%");
tv.setText("Watch Battery = " + String.valueOf(mConnection.mSdServer.mSdData.batteryPc) + "%");
if (mConnection.mSdServer.mSdData.batteryPc <= 20) {
tv.setBackgroundColor(alarmColour);
tv.setTextColor(alarmTextColour);

View File

@@ -78,10 +78,10 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
for (int i = 0; i < target.size(); i++) {
Header h = target.get(i);
Log.v(TAG,"found - "+h.title.toString());
if (h.title.toString().equals("Pebble Datasource")) {
Log.v(TAG, "found Pebble Datasource Header");
if (!dataSourceStr.equals("Pebble")) {
Log.v(TAG, "Removing pebble settings header");
if (h.title.toString().equals("Seizure Detector")) {
Log.v(TAG, "found Seizure Detector Header");
if (dataSourceStr.equals("Network")) {
Log.v(TAG, "Removing seizure detector settings header");
target.remove(i);
i = i-1;
}
@@ -94,14 +94,14 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
i = i -1;
}
}
//if (h.title.toString().equals("Camera Settings")) {
// Log.v(TAG, "found Camera Settings Header");
// if (!cameraEnabled) {
// Log.v(TAG, "Removing camera settings header");
// target.remove(i);
// i = i-1;
// }
//}
if (h.title.toString().equals("Pebble Datasource")) {
Log.v(TAG, "found Pebble Datasource Header");
if (!dataSourceStr.equals("Pebble")) {
Log.v(TAG, "Removing Pebble settings header");
target.remove(i);
i = i -1;
}
}
}
}
@@ -193,6 +193,16 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
}
}
public static class SeizureDetectorPrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.seizure_detector_prefs);
}
}
public static class PebbleDatasourcePrefsFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -213,14 +223,5 @@ public class PrefActivity extends PreferenceActivity implements SharedPreference
}
}
//public static class CameraPrefsFragment extends PreferenceFragment {
// @Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
// addPreferencesFromResource(R.xml.camera_prefs);
// }
//}
}

View File

@@ -63,6 +63,11 @@ public class SdData implements Parcelable {
public long alarmRatioThresh;
public long batteryPc;
/* Heart Rate Alarm Settings */
public boolean mHRAlarmActive = false;
public double mHRThreshMin = 40.0;
public double mHRTreshMax = 150.0;
/* Analysis results */
public Time dataTime = null;
public long alarmState;
@@ -78,6 +83,9 @@ public class SdData implements Parcelable {
public boolean pebbleAppRunning = false;
public boolean serverOK = false;
public boolean mHRAlarmStanding = false;
public double mHR = 0;
public SdData() {
simpleSpec = new int[10];
dataTime = new Time(Time.getCurrentTimezone());

View File

@@ -90,8 +90,9 @@ public abstract class SdDataSource {
// Force the data stored in this datasource to update in line with the JSON string encoded data provided.
// Used by webServer to update the NetworkPassiveDatasource
public void updateFromJSON(String jsonStr) {
public String updateFromJSON(String jsonStr) {
Log.v(TAG,"updateFromJSON - "+jsonStr);
return("OK");
}
/**

View File

@@ -147,7 +147,7 @@ public class SdDataSourceAw extends SdDataSource {
mName = "Android Wear";
// Set default settings from XML files (mContext is set by super().
PreferenceManager.setDefaultValues(mContext,
R.xml.pebble_datasource_prefs, true);
R.xml.seizure_detector_prefs, true);
}

View File

@@ -51,6 +51,7 @@ import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import static java.lang.Long.parseLong;
import static java.lang.Math.sqrt;
@@ -60,7 +61,7 @@ import static java.lang.Math.sqrt;
* function to send the data to this datasource.
* SdWebServer expects POST requests to /data and /settings URLs to send data or watch settings.
*/
public class SdDataSourceNetworkPassive extends SdDataSource {
public class SdDataSourceGarmin extends SdDataSource {
private Handler mHandler = new Handler();
private Timer mStatusTimer;
private Timer mSettingsTimer;
@@ -74,7 +75,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
private SdDataBroadcastReceiver mSdDataBroadcastReceiver;
private String TAG = "SdDataSourceNetPassive";
private String TAG = "SdDataSourceGarmin";
// Values for SD_MODE
private int SD_MODE_FFT = 0; // The original OpenSeizureDetector mode (FFT based)
@@ -110,8 +111,8 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
int mNSamp = 0;
public SdDataSourceNetworkPassive(Context context, Handler handler,
SdDataReceiver sdDataReceiver) {
public SdDataSourceGarmin(Context context, Handler handler,
SdDataReceiver sdDataReceiver) {
super(context, handler, sdDataReceiver);
mName = "NetworkPassive";
// Set default settings from XML files (mContext is set by super().
@@ -126,7 +127,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
*/
public void start() {
Log.v(TAG, "start()");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start()");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start()");
updatePrefs();
// Start timer to check status of watch regularly.
mDataStatusTime = new Time(Time.getCurrentTimezone());
@@ -134,7 +135,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
// as we get app data.
if (mStatusTimer == null) {
Log.v(TAG, "start(): starting status timer");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - starting status timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - starting status timer");
mStatusTimer = new Timer();
mStatusTimer.schedule(new TimerTask() {
@Override
@@ -144,11 +145,11 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
}, 0, mDataUpdatePeriod * 1000);
} else {
Log.v(TAG, "start(): status timer already running.");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - status timer already running??");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - status timer already running??");
}
if (mAlarmCheckTimer == null) {
Log.v(TAG, "start(): starting alarm check timer");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - starting alarm check timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - starting alarm check timer");
mAlarmCheckTimer = new Timer();
mAlarmCheckTimer.schedule(new TimerTask() {
@Override
@@ -158,12 +159,12 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
}, 0, 1000);
} else {
Log.v(TAG, "start(): alarm check timer already running.");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - alarm check timer already running??");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - alarm check timer already running??");
}
if (mSettingsTimer == null) {
Log.v(TAG, "start(): starting settings timer");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - starting settings timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - starting settings timer");
mSettingsTimer = new Timer();
mSettingsTimer.schedule(new TimerTask() {
@Override
@@ -173,7 +174,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
}, 0, 1000 * mSettingsPeriod); // ask for settings less frequently than we get data
} else {
Log.v(TAG, "start(): settings timer already running.");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.start() - settings timer already running??");
mUtil.writeToSysLogFile("SdDataSourceGarmin.start() - settings timer already running??");
}
mSdDataBroadcastReceiver = new SdDataBroadcastReceiver();
@@ -188,19 +189,36 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
*/
public void stop() {
Log.v(TAG, "stop()");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.stop()");
mUtil.writeToSysLogFile("SdDataSourceGarmin.stop()");
try {
// Stop the status timer
if (mStatusTimer != null) {
Log.v(TAG, "stop(): cancelling status timer");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.stop() - cancelling status timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.stop() - cancelling status timer");
mStatusTimer.cancel();
mStatusTimer.purge();
mStatusTimer = null;
}
// Stop the settings timer
if (mSettingsTimer != null) {
Log.v(TAG, "stop(): cancelling settings timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.stop() - cancelling settings timer");
mSettingsTimer.cancel();
mSettingsTimer.purge();
mSettingsTimer = null;
}
// Stop the alarm check timer
if (mAlarmCheckTimer != null) {
Log.v(TAG, "stop(): cancelling alarm check timer");
mUtil.writeToSysLogFile("SdDataSourceGarmin.stop() - cancelling alarm check timer");
mAlarmCheckTimer.cancel();
mAlarmCheckTimer.purge();
mAlarmCheckTimer = null;
}
} catch (Exception e) {
Log.v(TAG, "Error in stop() - " + e.toString());
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.stop() - error - "+e.toString());
mUtil.writeToSysLogFile("SdDataSourceGarmin.stop() - error - "+e.toString());
}
mContext.unregisterReceiver(mSdDataBroadcastReceiver);
}
@@ -211,7 +229,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
*/
public void updatePrefs() {
Log.v(TAG, "updatePrefs()");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.updatePrefs()");
mUtil.writeToSysLogFile("SdDataSourceGarmin.updatePrefs()");
SharedPreferences SP = PreferenceManager
.getDefaultSharedPreferences(mContext);
try {
@@ -242,79 +260,98 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
String prefStr;
prefStr = SP.getString("PebbleDebug", "SET_FROM_XML");
mDebug = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() Debug = " + mDebug);
if (prefStr != null) {
mDebug = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() Debug = " + mDebug);
prefStr = SP.getString("PebbleDisplaySpectrum", "SET_FROM_XML");
mDisplaySpectrum = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() DisplaySpectrum = " + mDisplaySpectrum);
prefStr = SP.getString("PebbleDisplaySpectrum", "SET_FROM_XML");
mDisplaySpectrum = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() DisplaySpectrum = " + mDisplaySpectrum);
prefStr = SP.getString("PebbleUpdatePeriod", "SET_FROM_XML");
mDataUpdatePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() DataUpdatePeriod = " + mDataUpdatePeriod);
prefStr = SP.getString("PebbleUpdatePeriod", "SET_FROM_XML");
mDataUpdatePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() DataUpdatePeriod = " + mDataUpdatePeriod);
prefStr = SP.getString("MutePeriod", "SET_FROM_XML");
mMutePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() MutePeriod = " + mMutePeriod);
prefStr = SP.getString("MutePeriod", "SET_FROM_XML");
mMutePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() MutePeriod = " + mMutePeriod);
prefStr = SP.getString("ManAlarmPeriod", "SET_FROM_XML");
mManAlarmPeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() ManAlarmPeriod = " + mManAlarmPeriod);
prefStr = SP.getString("ManAlarmPeriod", "SET_FROM_XML");
mManAlarmPeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() ManAlarmPeriod = " + mManAlarmPeriod);
prefStr = SP.getString("PebbleSdMode", "SET_FROM_XML");
mPebbleSdMode = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() PebbleSdMode = " + mPebbleSdMode);
prefStr = SP.getString("PebbleSdMode", "SET_FROM_XML");
mPebbleSdMode = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() PebbleSdMode = " + mPebbleSdMode);
prefStr = SP.getString("SampleFreq", "SET_FROM_XML");
mSampleFreq = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() SampleFreq = " + mSampleFreq);
prefStr = SP.getString("SampleFreq", "SET_FROM_XML");
mSampleFreq = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() SampleFreq = " + mSampleFreq);
prefStr = SP.getString("SamplePeriod", "SET_FROM_XML");
mSamplePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AnalysisPeriod = " + mSamplePeriod);
prefStr = SP.getString("SamplePeriod", "SET_FROM_XML");
mSamplePeriod = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AnalysisPeriod = " + mSamplePeriod);
prefStr = SP.getString("AlarmFreqMin", "SET_FROM_XML");
mAlarmFreqMin = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + mAlarmFreqMin);
prefStr = SP.getString("AlarmFreqMin", "SET_FROM_XML");
mAlarmFreqMin = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + mAlarmFreqMin);
prefStr = SP.getString("AlarmFreqMax", "SET_FROM_XML");
mAlarmFreqMax = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + mAlarmFreqMax);
prefStr = SP.getString("AlarmFreqMax", "SET_FROM_XML");
mAlarmFreqMax = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + mAlarmFreqMax);
prefStr = SP.getString("WarnTime", "SET_FROM_XML");
mWarnTime = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() WarnTime = " + mWarnTime);
prefStr = SP.getString("WarnTime", "SET_FROM_XML");
mWarnTime = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() WarnTime = " + mWarnTime);
prefStr = SP.getString("AlarmTime", "SET_FROM_XML");
mAlarmTime = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmTime = " + mAlarmTime);
prefStr = SP.getString("AlarmTime", "SET_FROM_XML");
mAlarmTime = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmTime = " + mAlarmTime);
prefStr = SP.getString("AlarmThresh", "SET_FROM_XML");
mAlarmThresh = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmThresh = " + mAlarmThresh);
prefStr = SP.getString("AlarmThresh", "SET_FROM_XML");
mAlarmThresh = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmThresh = " + mAlarmThresh);
prefStr = SP.getString("AlarmRatioThresh", "SET_FROM_XML");
mAlarmRatioThresh = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + mAlarmRatioThresh);
prefStr = SP.getString("AlarmRatioThresh", "SET_FROM_XML");
mAlarmRatioThresh = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + mAlarmRatioThresh);
mFallActive = SP.getBoolean("FallActive", false);
Log.v(TAG, "updatePrefs() FallActive = " + mFallActive);
mFallActive = SP.getBoolean("FallActive", false);
Log.v(TAG, "updatePrefs() FallActive = " + mFallActive);
prefStr = SP.getString("FallThreshMin", "SET_FROM_XML");
mFallThreshMin = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMin = " + mFallThreshMin);
prefStr = SP.getString("FallThreshMin", "SET_FROM_XML");
mFallThreshMin = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMin = " + mFallThreshMin);
prefStr = SP.getString("FallThreshMax", "SET_FROM_XML");
mFallThreshMax = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMax = " + mFallThreshMax);
prefStr = SP.getString("FallThreshMax", "SET_FROM_XML");
mFallThreshMax = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallThreshMax = " + mFallThreshMax);
prefStr = SP.getString("FallWindow", "SET_FROM_XML");
mFallWindow = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallWindow = " + mFallWindow);
prefStr = SP.getString("FallWindow", "SET_FROM_XML");
mFallWindow = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() FallWindow = " + mFallWindow);
mSdData.mHRAlarmActive = SP.getBoolean("HRAlarmActive", false);
Log.v(TAG, "updatePrefs() HRAlarmActive = " + mSdData.mHRAlarmActive);
prefStr = SP.getString("HRThreshMin", "SET_FROM_XML");
mSdData.mHRThreshMin = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() HRThreshMin = " + mSdData.mHRThreshMin);
prefStr = SP.getString("HRThreshMax", "SET_FROM_XML");
mSdData.mHRTreshMax = (short) Integer.parseInt(prefStr);
Log.v(TAG, "updatePrefs() HRThreshMax = " + mSdData.mHRTreshMax);
} else {
Log.v(TAG, "updatePrefs() - prefStr is null - WHY????");
mUtil.writeToSysLogFile("SdDataSourceGarmin.updatePrefs() - prefStr is null - WHY??");
Toast toast = Toast.makeText(mContext, "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
toast.show();
}
} catch (Exception ex) {
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.updatePrefs() - ERROR "+ex.toString());
mUtil.writeToSysLogFile("SdDataSourceGarmin.updatePrefs() - ERROR "+ex.toString());
Toast toast = Toast.makeText(mContext, "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
toast.show();
}
@@ -322,8 +359,10 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
// Force the data stored in this datasource to update in line with the JSON string encoded data provided.
// Used by webServer to update the NetworkPassiveDatasource
public void updateFromJSON(String jsonStr) {
// Used by webServer to update the GarminDatasource.
// Returns a message string that is passed back to the watch.
public String updateFromJSON(String jsonStr) {
String retVal = "undefined";
Log.v(TAG,"updateFromJSON - "+jsonStr);
try {
@@ -334,6 +373,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
Log.v(TAG,"updateFromJSON - dataType="+dataTypeStr);
if (dataTypeStr.equals("raw")) {
Log.v(TAG,"updateFromJSON - processing raw data");
mSdData.mHR = dataObject.getDouble("HR");
JSONArray accelVals = dataObject.getJSONArray("data");
Log.v(TAG, "Received " + accelVals.length() + " acceleration values");
int i;
@@ -343,6 +383,11 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
mNSamp = accelVals.length();
mWatchAppRunningCheck = true;
doAnalysis();
if (mSdData.haveSettings == false) {
retVal = "sendSettings";
} else {
retVal = "OK";
}
} else if (dataTypeStr.equals("settings")){
Log.v(TAG,"updateFromJSON - processing settings");
mSamplePeriod = (short)dataObject.getInt("analysisPeriod");
@@ -352,13 +397,17 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
mSdData.haveSettings = true;
mSdData.mSampleFreq = mSampleFreq;
mWatchAppRunningCheck = true;
retVal = "OK";
} else {
Log.v(TAG,"updateFromJSON - unrecognised dataType "+dataTypeStr);
Log.e(TAG,"updateFromJSON - unrecognised dataType "+dataTypeStr);
retVal = "ERROR";
}
} catch (Exception e) {
Log.v(TAG,"updateFromJSON - Error Parsing JSON String - "+e.toString());
Log.e(TAG,"updateFromJSON - Error Parsing JSON String - "+e.toString());
e.printStackTrace();
retVal = "ERROR";
}
return(retVal);
}
/**
@@ -448,6 +497,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
mSdData.simpleSpec[i] = (int)simpleSpec[i]/1000;
}
Log.v(TAG, "simpleSpec = " + Arrays.toString(mSdData.simpleSpec));
// Because we have received data, set flag to show watch app running.
mWatchAppRunningCheck = true;
mSdDataReceiver.onSdDataReceived(mSdData); // and tell SdServer we have received data.
@@ -479,7 +529,7 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
if (tdiff > (mDataUpdatePeriod + mFaultTimerPeriod) * 1000) {
Log.v(TAG, "getStatus() - Watch App Not Running");
mUtil.writeToSysLogFile("SdDataSourceNetworkPassive.getStatus() - Watch App not Running");
mUtil.writeToSysLogFile("SdDataSourceGarmin.getStatus() - Watch App not Running");
//mDataStatusTime.setToNow();
mSdData.roiPower = -1;
mSdData.specPower = -1;
@@ -551,6 +601,17 @@ public class SdDataSourceNetworkPassive extends SdDataSource {
}
}
Log.v(TAG, "inAlarm=" + inAlarm + ", alarmState = " + mSdData.alarmState + " alarmCount=" + mAlarmCount + " mAlarmTime=" + mAlarmTime);
/* Check Heart Rate against alarm settings */
if (mSdData.mHRAlarmActive) {
Log.v(TAG,"Checking HR Alarm");
if ((mSdData.mHR > mSdData.mHRTreshMax) || (mSdData.mHR < mSdData.mHRThreshMin)) {
Log.i(TAG, "Heart Rate Abnormal - " + mSdData.mHR + " bpm");
mSdData.mHRAlarmStanding = true;
} else {
mSdData.mHRAlarmStanding = false;
}
}
}
}

View File

@@ -153,7 +153,7 @@ public class SdDataSourcePebble extends SdDataSource {
mName = "Pebble";
// Set default settings from XML files (mContext is set by super().
PreferenceManager.setDefaultValues(mContext,
R.xml.pebble_datasource_prefs, true);
R.xml.seizure_detector_prefs, true);
}

View File

@@ -210,10 +210,10 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceNetwork");
mSdDataSource = new SdDataSourceNetwork(this.getApplicationContext(), mHandler, this);
break;
case "NetworkPassive":
Log.v(TAG, "Selecting Network (Passive) DataSource");
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceNetworkPassive");
mSdDataSource = new SdDataSourceNetworkPassive(this.getApplicationContext(), mHandler, this);
case "Garmin":
Log.v(TAG, "Selecting Garmin DataSource");
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceGarmin");
mSdDataSource = new SdDataSourceGarmin(this.getApplicationContext(), mHandler, this);
break;
default:
Log.v(TAG, "Datasource " + mSdDataSourceName + " not recognised - Exiting");
@@ -333,6 +333,17 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
// Stop the Cancel Alarm Latch timer
stopLatchTimer();
// Stop the status timer
if (dataLogTimer != null) {
Log.v(TAG, "stop(): cancelling Data logger timer");
mUtil.writeToSysLogFile("onDestroy() - cancelling data log timer");
dataLogTimer.cancel();
dataLogTimer.purge();
dataLogTimer = null;
}
try {
// Cancel the notification.
Log.v(TAG, "onDestroy(): cancelling notification");
@@ -342,6 +353,11 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
Log.v(TAG, "onDestroy(): stopping web server");
mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping Web Server");
stopWebServer();
mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing mToneGenerator");
mToneGenerator.release();
mToneGenerator = null;
// stop this service.
Log.v(TAG, "onDestroy(): calling stopSelf()");
mUtil.writeToSysLogFile("SdServer.onDestroy() - stopping self");
@@ -352,9 +368,6 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
mUtil.writeToSysLogFile("SdServer.onDestroy() -error " + e.toString());
}
mUtil.writeToSysLogFile("SdServer.onDestroy() - releasing mToneGenerator");
mToneGenerator.release();
mToneGenerator = null;
}
@@ -516,8 +529,36 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
mSMSTime = tnow;
}
}
}
// Handle heart rate alarm
if ((sdData.mHRAlarmActive) && (sdData.mHRAlarmStanding)) {
sdData.alarmPhrase = "HR ABNORMAL";
if (mLogAlarms) {
Log.v(TAG, "***HEART RATE*** - Logging to SD Card");
writeAlarmToSD();
logData();
} else {
Log.v(TAG, "***HEART RATE***");
}
// Make alarm beep tone
alarmBeep();
// 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;
}
}
}
// Fault
if ((sdData.alarmState) == 4 || (sdData.alarmState == 7)) {
sdData.alarmPhrase = "FAULT";
@@ -553,7 +594,7 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
mToneGenerator.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, duration);
Log.v(TAG, "beep()");
} else {
mUtil.showToast("Warming mToneGenerator is null - not beeping!!!");
mUtil.showToast("Warning mToneGenerator is null - not beeping!!!");
Log.v(TAG, "beep() - Warming mToneGenerator is null - not beeping!!!");
mUtil.writeToSysLogFile("SdServer.beep() - mToneGenerator is null???");
}
@@ -660,16 +701,30 @@ public class SdServer extends Service implements SdDataReceiver, SdLocationRecei
private void sendSMS(String phoneNo, String msgStr) {
Log.i(TAG, "sendSMS() - Sending to " + phoneNo);
try {
SmsManager sm = SmsManager.getDefault();
sm.sendTextMessage(phoneNo, null, msgStr,
null, null);
} catch (Exception e) {
Log.e(TAG, "sendSMS - Failed to send SMS Message");
mUtil.writeToSysLogFile("sendSMS - Failed to send SMS Message");
Log.e(TAG, e.toString());
mUtil.showToast("ERROR: FAILED TO SEND SMS MESSAGE");
}
}
private void sendSMSIntent(String phoneNo, String msgStr) {
Log.i(TAG, "sendSMSIntent() - Sending to " + phoneNo);
// sm.sendTextMessage(mSMSNumbers[i], null, mSMSMsgStr + " - " + dateStr, null, null);
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("smsto:")); //, HTTP.PLAIN_TEXT_TYPE);
intent.putExtra("sms_body", msgStr);
intent.putExtra("address", phoneNo);
if (intent.resolveActivity(getPackageManager()) != null) {
Log.i(TAG, "sendSMS() - Starting Activity to send SMS....");
Log.i(TAG, "sendSMSIntent() - Starting Activity to send SMS....");
startActivity(intent);
} else {
Log.e(TAG, "sendSMS() - Failed to send SMS - can not find activity do do it");
Log.e(TAG, "sendSMSIntent() - Failed to send SMS - can not find activity do do it");
}
}

View File

@@ -95,15 +95,10 @@ public class SdWebServer extends NanoHTTPD {
// Send the data to the SdDataSource so the app can pick it up.
if (parameters != null) {
Log.v(TAG,"passing parameters to data source");
mSdServer.mSdDataSource.updateFromJSON(parameters.get("dataObj").toString());
answer = mSdServer.mSdDataSource.updateFromJSON(parameters.get("dataObj").toString());
} else {
Log.v(TAG,"Passing postData to data source");
mSdServer.mSdDataSource.updateFromJSON(files.get("postData"));
}
if (mSdData.haveSettings) {
answer = "OK";
} else {
answer = "sendSettings";
answer = mSdServer.mSdDataSource.updateFromJSON(files.get("postData"));
}
break;
default:
@@ -136,7 +131,15 @@ public class SdWebServer extends NanoHTTPD {
Log.v(TAG, "WebServer.serve() - POST /settings - receiving data from device: parameters=" + parameters.toString());
Log.v(TAG, " header=" + header.toString());
Log.v(TAG, " files=" + files.toString());
mSdServer.mSdDataSource.updateFromJSON(parameters.toString());
// Send the data to the SdDataSource so the app can pick it up.
if (parameters != null) {
Log.v(TAG,"passing parameters to data source");
answer = mSdServer.mSdDataSource.updateFromJSON(parameters.get("dataObj").toString());
} else {
Log.v(TAG,"Passing postData to data source");
answer = mSdServer.mSdDataSource.updateFromJSON(files.get("postData"));
}
//mSdServer.mSdDataSource.updateFromJSON(parameters.toString());
break;
default:
Log.v(TAG, "WebServer.serve() - Unrecognised method - " + method);
@@ -189,7 +192,7 @@ public class SdWebServer extends NanoHTTPD {
answer = "Unknown URI: ";
}
}
Log.v(TAG,"WebServer.serve() - returning "+answer);
return new NanoHTTPD.Response(answer);
}

View File

@@ -4,13 +4,13 @@
<item>"Pebble Watch"</item>
<item>"Android Wear"</item>
<item>"Network"</item>
<item>"Network (passive)"</item>
<item>"Garmin"</item>
</string-array>
<string-array name="datasource_list_values">
<item>"Pebble"</item>
<item>"AndroidWear"</item>
<item>"Network"</item>
<item>"NetworkPassive"</item>
<item>"Garmin"</item>
</string-array>
</resources>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Arrays used to produce list selections in pebble_datasource_prefs.xml -->
<!-- Arrays used to produce list selections in seizure_detector_prefsxml -->
<resources>
<string-array name="pebble_debug_list">
<item>"Debug OFF"</item>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Heart Rate Alarm Settings">
<CheckBoxPreference
android:defaultValue="false"
android:key="HRAlarmActive"
android:summary=""
android:title="Heart Rate Alarm Enabled" />
<EditTextPreference
android:defaultValue="40"
android:key="HRThreshMin"
android:summary=""
android:title="Heart Rate Min Threshold (bpm)" />
<EditTextPreference
android:defaultValue="150"
android:key="HRThreshMax"
android:summary=""
android:title="Heart Rate Max Threshold (bpm)" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,7 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The ListPreference data is defined in pebble_datasource_values.xml -->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="User Interface Settings">
<EditTextPreference
android:defaultValue="5"
@@ -28,44 +26,8 @@
android:dialogTitle="Select Display Spectrum Mode" />
</PreferenceCategory>
<PreferenceCategory android:title="Seizure Detector Settings">
<EditTextPreference
android:defaultValue="5"
android:key="WarnTime"
android:summary="Time to wait before initiating warning (Default = 5 sec)"
android:title="WarnTime (sec)" />
<EditTextPreference
android:defaultValue="10"
android:key="AlarmTime"
android:summary="Time to wait before initiating alarm (Default = 10 sec)"
android:title="AlarmTime (sec)" />
<EditTextPreference
android:defaultValue="100"
android:key="AlarmThresh"
android:summary="Alarm Threshold (Default = 100)"
android:title="AlarmThresh" />
<EditTextPreference
android:defaultValue="50"
android:key="AlarmRatioThresh"
android:summary="Alarm Ratio Threshold (Default = 50). Increase this value to reduce sensitivity if false alarms are a problem."
android:title="AlarmRatioThresh" />
<EditTextPreference
android:defaultValue="3"
android:key="AlarmFreqMin"
android:summary="Minimum Frequency of ROI (Hz) (Default = 3 Hz)"
android:title="AlarmFreqMin (Hz)" />
<EditTextPreference
android:defaultValue="10"
android:key="AlarmFreqMax"
android:summary="Maximum Frequency of ROI (Hz) (Default = 10 Hz)"
android:title="AlarmFreqMax (Hz)" />
<EditTextPreference
android:defaultValue="5"
android:key="SamplePeriod"
android:summary="Period (in seconds) between data analyses"
android:title="SamplePeriod (sec)" />
<PreferenceCategory android:title="Analysis">
<ListPreference
android:key="PebbleSdMode"
android:title="Seizure Detector Mode"
@@ -85,9 +47,7 @@
android:enabled="true"
/>
</PreferenceCategory>
<PreferenceCategory android:title="Fall Detector Settings">
<CheckBoxPreference
android:defaultValue="false"
@@ -128,4 +88,5 @@
android:summary="Period (seconds) that we wait for data from the watch before assuming the watch app is not running and re-starting it."
android:title="Period (sec) we wait for data before restarting watch app." />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -12,22 +12,20 @@
android:title="Alarms"
android:summary="Alarms Preferences" />
<header android:fragment="uk.org.openseizuredetector.PrefActivity$SeizureDetectorPrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="Seizure Detector"
android:summary="Seizure Detector Preferences" />
<header android:fragment="uk.org.openseizuredetector.PrefActivity$PebbleDatasourcePrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="Pebble Datasource"
android:summary="Pebble Datasource Preferences" />
android:title="Network Datasource"
android:summary="Network Datasource Preferences" />
<header android:fragment="uk.org.openseizuredetector.PrefActivity$NetworkDatasourcePrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="Network Datasource"
android:summary="Network Datasource Preferences" />
<!--<header android:fragment="uk.org.openseizuredetector.PrefActivity$CameraPrefsFragment"
android:icon="@drawable/icon_24x24"
android:title="Camera Settings"
android:summary="IP Camera Preferences"
android:enabled="false"
/>-->
</preference-headers>

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- The ListPreference data is defined in pebble_datasource_values.xml -->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Seizure Detector Settings">
<EditTextPreference
android:defaultValue="5"
android:key="WarnTime"
android:summary="Time to wait before initiating warning (Default = 5 sec)"
android:title="WarnTime (sec)" />
<EditTextPreference
android:defaultValue="10"
android:key="AlarmTime"
android:summary="Time to wait before initiating alarm (Default = 10 sec)"
android:title="AlarmTime (sec)" />
<EditTextPreference
android:defaultValue="100"
android:key="AlarmThresh"
android:summary="Alarm Threshold (Default = 100)"
android:title="AlarmThresh" />
<EditTextPreference
android:defaultValue="50"
android:key="AlarmRatioThresh"
android:summary="Alarm Ratio Threshold (Default = 50). Increase this value to reduce sensitivity if false alarms are a problem."
android:title="AlarmRatioThresh" />
<EditTextPreference
android:defaultValue="3"
android:key="AlarmFreqMin"
android:summary="Minimum Frequency of ROI (Hz) (Default = 3 Hz)"
android:title="AlarmFreqMin (Hz)" />
<EditTextPreference
android:defaultValue="10"
android:key="AlarmFreqMax"
android:summary="Maximum Frequency of ROI (Hz) (Default = 10 Hz)"
android:title="AlarmFreqMax (Hz)" />
<EditTextPreference
android:defaultValue="5"
android:key="SamplePeriod"
android:summary="Period (in seconds) between data analyses"
android:title="SamplePeriod (sec)" />
</PreferenceCategory>
<PreferenceCategory android:title="Heart Rate Alarm Settings">
<CheckBoxPreference
android:defaultValue="false"
android:key="HRAlarmActive"
android:summary=""
android:title="Heart Rate Alarm Enabled" />
<EditTextPreference
android:defaultValue="40"
android:key="HRThreshMin"
android:summary=""
android:title="Heart Rate Min Threshold (bpm)" />
<EditTextPreference
android:defaultValue="150"
android:key="HRThreshMax"
android:summary=""
android:title="Heart Rate Max Threshold (bpm)" />
</PreferenceCategory>
</PreferenceScreen>