diff --git a/app/release/app-release-3.6.1g.apk b/app/release/app-release-3.6.1g.apk new file mode 100644 index 0000000..ad07f22 Binary files /dev/null and b/app/release/app-release-3.6.1g.apk differ diff --git a/app/release/app-release.apk b/app/release/app-release.apk index ff30653..ad07f22 100644 Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json index 1c2b8ea..a4c5f4f 100644 --- a/app/release/output-metadata.json +++ b/app/release/output-metadata.json @@ -11,8 +11,8 @@ "type": "SINGLE", "filters": [], "properties": [], - "versionCode": 79, - "versionName": "3.6.1f", + "versionCode": 80, + "versionName": "3.6.1g", "enabled": true, "outputFile": "app-release.apk" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a34b47a..b9e4d48 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="80" + android:versionName="3.6.1g"> diff --git a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java index 3e75e27..3f23fe6 100644 --- a/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java +++ b/app/src/main/java/uk/org/openseizuredetector/SdDataSource.java @@ -45,6 +45,7 @@ import java.util.TimerTask; interface SdDataReceiver { public void onSdDataReceived(SdData sdData); + public void onSdDataFault(SdData sdData); } @@ -97,7 +98,6 @@ public abstract class SdDataSource { private int ACCEL_SCALE_FACTOR = 1000; // Amount by which to reduce analysis results to scale to be comparable to analysis on Pebble. - private int mAlarmCount; protected String mBleDeviceAddr; protected String mBleDeviceName; @@ -114,6 +114,7 @@ public abstract class SdDataSource { /** * Returns the SdData object stored by this class. + * * @return */ public SdData getSdData() { @@ -211,7 +212,7 @@ public abstract class SdDataSource { } catch (Exception e) { Log.v(TAG, "Error in stop() - " + e.toString()); - mUtil.writeToSysLogFile("SDDataSource.stop() - error - "+e.toString()); + mUtil.writeToSysLogFile("SDDataSource.stop() - error - " + e.toString()); } } @@ -220,7 +221,7 @@ public abstract class SdDataSource { * Install the watch app on the watch. */ public void installWatchApp() { - Log.v(TAG,"installWatchApp"); + Log.v(TAG, "installWatchApp"); try { String url = "http://www.openseizuredetector.org.uk/?page_id=1207"; Intent i = new Intent(Intent.ACTION_VIEW); @@ -233,9 +234,13 @@ public abstract class SdDataSource { } } - public void startPebbleApp() { Log.v(TAG,"startPebbleApp()"); } + public void startPebbleApp() { + Log.v(TAG, "startPebbleApp()"); + } - public void acceptAlarm() { Log.v(TAG,"acceptAlarm()"); } + public void acceptAlarm() { + Log.v(TAG, "acceptAlarm()"); + } // Force the data stored in this datasource to update in line with the JSON string encoded data provided. // Used by webServer to update the GarminDatasource. @@ -246,16 +251,17 @@ public abstract class SdDataSource { String watchFwVersion; String sdVersion; String sdName; - Log.v(TAG,"updateFromJSON - "+jsonStr); + JSONArray accelVals = null; + Log.v(TAG, "updateFromJSON - " + jsonStr); try { JSONObject mainObject = new JSONObject(jsonStr); //JSONObject dataObject = mainObject.getJSONObject("dataObj"); JSONObject dataObject = mainObject; String dataTypeStr = dataObject.getString("dataType"); - Log.v(TAG,"updateFromJSON - dataType="+dataTypeStr); + Log.v(TAG, "updateFromJSON - dataType=" + dataTypeStr); if (dataTypeStr.equals("raw")) { - Log.v(TAG,"updateFromJSON - processing raw data"); + Log.v(TAG, "updateFromJSON - processing raw data"); try { mSdData.mHR = dataObject.getDouble("HR"); } catch (JSONException e) { @@ -268,8 +274,12 @@ public abstract class SdDataSource { // if we get 'null' HR (For example if the heart rate is not working) mMute = 0; } - JSONArray accelVals = dataObject.getJSONArray("data"); - Log.v(TAG, "Received " + accelVals.length() + " acceleration values"); + accelVals = dataObject.getJSONArray("data"); + Log.v(TAG, "Received " + accelVals.length() + " acceleration values, rawData Length is " + mSdData.rawData.length); + if (accelVals.length() > mSdData.rawData.length) { + mUtil.writeToSysLogFile("ERROR: Received " + accelVals.length() + " acceleration values, but rawData storage length is " + + mSdData.rawData.length); + } int i; for (i = 0; i < accelVals.length(); i++) { mSdData.rawData[i] = accelVals.getInt(i); @@ -283,26 +293,26 @@ public abstract class SdDataSource { } else { retVal = "OK"; } - } else if (dataTypeStr.equals("settings")){ - Log.v(TAG,"updateFromJSON - processing settings"); - mSamplePeriod = (short)dataObject.getInt("analysisPeriod"); - mSampleFreq = (short)dataObject.getInt("sampleFreq"); - mSdData.batteryPc = (short)dataObject.getInt("battery"); - Log.v(TAG,"updateFromJSON - mSamplePeriod="+mSamplePeriod+" mSampleFreq="+mSampleFreq); + } else if (dataTypeStr.equals("settings")) { + Log.v(TAG, "updateFromJSON - processing settings"); + mSamplePeriod = (short) dataObject.getInt("analysisPeriod"); + mSampleFreq = (short) dataObject.getInt("sampleFreq"); + mSdData.batteryPc = (short) dataObject.getInt("battery"); + Log.v(TAG, "updateFromJSON - mSamplePeriod=" + mSamplePeriod + " mSampleFreq=" + mSampleFreq); mUtil.writeToSysLogFile("SDDataSource.updateFromJSON - Settings Received"); - mUtil.writeToSysLogFile(" * mSamplePeriod="+mSamplePeriod+" mSampleFreq="+mSampleFreq); - mUtil.writeToSysLogFile(" * batteryPc = "+mSdData.batteryPc); + mUtil.writeToSysLogFile(" * mSamplePeriod=" + mSamplePeriod + " mSampleFreq=" + mSampleFreq); + mUtil.writeToSysLogFile(" * batteryPc = " + mSdData.batteryPc); try { watchPartNo = dataObject.getString("watchPartNo"); watchFwVersion = dataObject.getString("watchFwVersion"); sdVersion = dataObject.getString("sdVersion"); sdName = dataObject.getString("sdName"); - mUtil.writeToSysLogFile(" * sdName = "+sdName+" version "+sdVersion); - mUtil.writeToSysLogFile(" * watchPartNo = "+watchPartNo+" fwVersion "+watchFwVersion); + mUtil.writeToSysLogFile(" * sdName = " + sdName + " version " + sdVersion); + mUtil.writeToSysLogFile(" * watchPartNo = " + watchPartNo + " fwVersion " + watchFwVersion); } catch (Exception e) { - Log.e(TAG,"updateFromJSON - Error Parsing V3.2 JSON String - "+e.toString()); - mUtil.writeToSysLogFile("updateFromJSON - Error Parsing V3.2 JSON String - "+ jsonStr + " - " +e.toString()); + Log.e(TAG, "updateFromJSON - Error Parsing V3.2 JSON String - " + e.toString()); + mUtil.writeToSysLogFile("updateFromJSON - Error Parsing V3.2 JSON String - " + jsonStr + " - " + e.toString()); mUtil.writeToSysLogFile(" This is probably because of an out of date watch app - please upgrade!"); e.printStackTrace(); } @@ -311,28 +321,34 @@ public abstract class SdDataSource { mWatchAppRunningCheck = true; retVal = "OK"; } else { - Log.e(TAG,"updateFromJSON - unrecognised dataType "+dataTypeStr); + Log.e(TAG, "updateFromJSON - unrecognised dataType " + dataTypeStr); retVal = "ERROR"; } } catch (Exception e) { - Log.e(TAG,"updateFromJSON - Error Parsing JSON String - "+ jsonStr+" - "+e.toString()); - mUtil.writeToSysLogFile("updateFromJSON - Error Parsing JSON String - "+ jsonStr + " - "+e.toString()); - mUtil.writeToSysLogFile("updateFromJSON: Exception at Line Number: "+e.getCause().getStackTrace()[0].getLineNumber()+", "+e.getCause().getStackTrace()[0].toString()); + Log.e(TAG, "updateFromJSON - Error Parsing JSON String - " + jsonStr + " - " + e.toString()); + mUtil.writeToSysLogFile("updateFromJSON - Error Parsing JSON String - " + jsonStr + " - " + e.toString()); + mUtil.writeToSysLogFile("updateFromJSON: Exception at Line Number: " + e.getCause().getStackTrace()[0].getLineNumber() + ", " + e.getCause().getStackTrace()[0].toString()); + if (accelVals == null) { + mUtil.writeToSysLogFile("updateFromJSON: accelVals is null when exception thrown"); + } else { + mUtil.writeToSysLogFile("updateFromJSON: Received " + accelVals.length() + " acceleration values"); + } e.printStackTrace(); retVal = "ERROR"; } - return(retVal); + return (retVal); } /** * Calculate the magnitude of entry i in the fft array fft + * * @param fft * @param i * @return magnitude ( Re*Re + Im*Im ) */ private double getMagnitude(double[] fft, int i) { double mag; - mag = (fft[2*i]*fft[2*i] + fft[2*i + 1] * fft[2*i +1]); + mag = (fft[2 * i] * fft[2 * i] + fft[2 * i + 1] * fft[2 * i + 1]); return mag; } @@ -341,82 +357,98 @@ public abstract class SdDataSource { * and populate the output data structure mSdData */ protected void doAnalysis() { - // FIXME - Use specified sampleFreq, not this hard coded one - mSampleFreq = 25; - double freqRes = 1.0*mSampleFreq/mSdData.mNsamp; - Log.v(TAG,"doAnalysis(): mSampleFreq="+mSampleFreq+" mNSamp="+mSdData.mNsamp+": freqRes="+freqRes); - // Set the frequency bounds for the analysis in fft output bin numbers. - int nMin = (int)(mAlarmFreqMin/freqRes); - int nMax = (int)(mAlarmFreqMax /freqRes); - Log.v(TAG,"doAnalysis(): mAlarmFreqMin="+mAlarmFreqMin+", nMin="+nMin - +", mAlarmFreqMax="+mAlarmFreqMax+", nMax="+nMax); - // Calculate the bin number of the cutoff frequency - int nFreqCutoff = (int)(mFreqCutoff /freqRes); - Log.v(TAG,"mFreqCutoff = "+mFreqCutoff+", nFreqCutoff="+nFreqCutoff); + int nMin = 0; + int nMax = 0; + int nFreqCutoff = 0; + double[] fft = null; + try { + // FIXME - Use specified sampleFreq, not this hard coded one + mSampleFreq = 25; + double freqRes = 1.0 * mSampleFreq / mSdData.mNsamp; + Log.v(TAG, "doAnalysis(): mSampleFreq=" + mSampleFreq + " mNSamp=" + mSdData.mNsamp + ": freqRes=" + freqRes); + // Set the frequency bounds for the analysis in fft output bin numbers. + nMin = (int) (mAlarmFreqMin / freqRes); + nMax = (int) (mAlarmFreqMax / freqRes); + Log.v(TAG, "doAnalysis(): mAlarmFreqMin=" + mAlarmFreqMin + ", nMin=" + nMin + + ", mAlarmFreqMax=" + mAlarmFreqMax + ", nMax=" + nMax); + // Calculate the bin number of the cutoff frequency + nFreqCutoff = (int) (mFreqCutoff / freqRes); + Log.v(TAG, "mFreqCutoff = " + mFreqCutoff + ", nFreqCutoff=" + nFreqCutoff); - DoubleFFT_1D fftDo = new DoubleFFT_1D(mSdData.mNsamp); - double[] fft = new double[mSdData.mNsamp * 2]; - ///System.arraycopy(mAccData, 0, fft, 0, mNsamp); - System.arraycopy(mSdData.rawData, 0, fft, 0, mSdData.mNsamp); - fftDo.realForward(fft); + DoubleFFT_1D fftDo = new DoubleFFT_1D(mSdData.mNsamp); + fft = new double[mSdData.mNsamp * 2]; + ///System.arraycopy(mAccData, 0, fft, 0, mNsamp); + System.arraycopy(mSdData.rawData, 0, fft, 0, mSdData.mNsamp); + fftDo.realForward(fft); - // Calculate the whole spectrum power (well a value equivalent to it that avoids square root calculations - // and zero any readings that are above the frequency cutoff. - double specPower = 0; - for (int i = 1; i < mSdData.mNsamp / 2; i++) { - if (i <= nFreqCutoff) { - specPower = specPower + getMagnitude(fft,i); - } else { - fft[2*i] = 0.; - fft[2*i+1] = 0.; + // Calculate the whole spectrum power (well a value equivalent to it that avoids square root calculations + // and zero any readings that are above the frequency cutoff. + double specPower = 0; + for (int i = 1; i < mSdData.mNsamp / 2; i++) { + if (i <= nFreqCutoff) { + specPower = specPower + getMagnitude(fft, i); + } else { + fft[2 * i] = 0.; + fft[2 * i + 1] = 0.; + } } - } - //Log.v(TAG,"specPower = "+specPower); - //specPower = specPower/(mSdData.mNsamp/2); - specPower = specPower/mSdData.mNsamp/2; - //Log.v(TAG,"specPower = "+specPower); + //Log.v(TAG,"specPower = "+specPower); + //specPower = specPower/(mSdData.mNsamp/2); + specPower = specPower / mSdData.mNsamp / 2; + //Log.v(TAG,"specPower = "+specPower); - // Calculate the Region of Interest power and power ratio. - double roiPower = 0; - for (int i=nMin;i