diff --git a/app/release/app-release-2.6.0.apk b/app/release/app-release-2.6.0.apk new file mode 100644 index 0000000..909d37c Binary files /dev/null and b/app/release/app-release-2.6.0.apk differ diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 8096913..d13dd84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -9,7 +9,7 @@ - + diff --git a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java index 9bbe194..b80a21d 100644 --- a/app/src/main/java/uk/org/openseizuredetector/MainActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/MainActivity.java @@ -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); diff --git a/app/src/main/java/uk/org/openseizuredetector/PrefActivity.java b/app/src/main/java/uk/org/openseizuredetector/PrefActivity.java index 1282b34..721c122 100644 --- a/app/src/main/java/uk/org/openseizuredetector/PrefActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/PrefActivity.java @@ -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); - // } - //} } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdData.java b/app/src/main/java/uk/org/openseizuredetector/SdData.java index 4b3347d..3849c53 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdData.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdData.java @@ -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()); diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java index f424082..2dbd45f 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java @@ -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"); } /** diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceAw.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceAw.java index 9b9e467..e96b578 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceAw.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceAw.java @@ -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); } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetworkPassive.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceGarmin.java similarity index 71% rename from app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetworkPassive.java rename to app/src/main/java/uk/org/openseizuredetector/SdDataSourceGarmin.java index 0da3a7a..c4487fb 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSourceNetworkPassive.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSourceGarmin.java @@ -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; + } + } } } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java index 1f758bb..a98ced5 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSourcePebble.java @@ -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); } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdServer.java b/app/src/main/java/uk/org/openseizuredetector/SdServer.java index f1d77fc..14fedcc 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdServer.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdServer.java @@ -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"); } } diff --git a/app/src/main/java/uk/org/openseizuredetector/SdWebServer.java b/app/src/main/java/uk/org/openseizuredetector/SdWebServer.java index c8749bd..3fcf482 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdWebServer.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdWebServer.java @@ -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); } diff --git a/app/src/main/res/values/datasource_list.xml b/app/src/main/res/values/datasource_list.xml index 7d521fe..fcc6732 100644 --- a/app/src/main/res/values/datasource_list.xml +++ b/app/src/main/res/values/datasource_list.xml @@ -4,13 +4,13 @@ "Pebble Watch" "Android Wear" "Network" - "Network (passive)" + "Garmin" "Pebble" "AndroidWear" "Network" - "NetworkPassive" + "Garmin" \ No newline at end of file diff --git a/app/src/main/res/values/pebble_datasource_values.xml b/app/src/main/res/values/pebble_datasource_values.xml index 9aaf8b0..cb652c9 100644 --- a/app/src/main/res/values/pebble_datasource_values.xml +++ b/app/src/main/res/values/pebble_datasource_values.xml @@ -1,5 +1,5 @@ - + "Debug OFF" diff --git a/app/src/main/res/xml/garmin_datasource_prefs.xml b/app/src/main/res/xml/garmin_datasource_prefs.xml new file mode 100644 index 0000000..972ee7a --- /dev/null +++ b/app/src/main/res/xml/garmin_datasource_prefs.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/pebble_datasource_prefs.xml b/app/src/main/res/xml/pebble_datasource_prefs.xml index 396c59a..df5dbe7 100644 --- a/app/src/main/res/xml/pebble_datasource_prefs.xml +++ b/app/src/main/res/xml/pebble_datasource_prefs.xml @@ -1,7 +1,5 @@ - - + - - - - - - - - - + - - - + + \ No newline at end of file diff --git a/app/src/main/res/xml/preference_headers.xml b/app/src/main/res/xml/preference_headers.xml index 880c4a9..da8965e 100644 --- a/app/src/main/res/xml/preference_headers.xml +++ b/app/src/main/res/xml/preference_headers.xml @@ -12,22 +12,20 @@ android:title="Alarms" android:summary="Alarms Preferences" /> +
+
+ android:title="Network Datasource" + android:summary="Network Datasource Preferences" />
- - \ No newline at end of file diff --git a/app/src/main/res/xml/seizure_detector_prefs.xml b/app/src/main/res/xml/seizure_detector_prefs.xml new file mode 100644 index 0000000..0cfcedd --- /dev/null +++ b/app/src/main/res/xml/seizure_detector_prefs.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + +