V3.6.0 - Added phone sensor data source for demonstration / testing without a watch

This commit is contained in:
Graham Jones
2020-09-13 21:41:33 +01:00
parent 4e1948a3aa
commit fb4597284d
11 changed files with 200 additions and 12 deletions

View File

@@ -1,5 +1,7 @@
OpenSeizureDetector Android App - Change Log
============================================
V3.6.0 - Sep 2020
- Added a phone sensor datasource, primarily for people to use for testing without needing a watch.
V3.5.0 - Aug 2020
- Added broadcast to request phone call dial alert (handled by separate app OpenSeizureDetector Dialler).
- Added UUID string to SMS alerts so they can be detected by a custom SMS receiver on the carer's phone.

Binary file not shown.

View File

@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"properties": [],
"versionCode": 72,
"versionName": "3.5.0a",
"versionCode": 73,
"versionName": "3.6.0",
"enabled": true,
"outputFile": "app-release.apk"
}

View File

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="uk.org.openseizuredetector"
android:versionCode="72"
android:versionName="3.5.0a">
android:versionCode="73"
android:versionName="3.6.0">
<!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

View File

@@ -176,7 +176,9 @@ public class SdDataSourceBLE extends SdDataSource {
return;
}
// Un-register for BLE Notifications.
if (mOsdChar != null) {
setCharacteristicNotification(mOsdChar, false);
}
mBluetoothGatt.disconnect();
if (mBluetoothGatt == null) {
@@ -314,6 +316,7 @@ public class SdDataSourceBLE extends SdDataSource {
mSdData.watchAppRunning = true;
for (i = 0; i < rawData.length; i++) {
mSdData.rawData[i] = rawData[i];
//Log.v(TAG,"onDataReceived() i="+i+", "+rawData[i]);
}
mSdData.mNsamp = rawData.length;
//mNSamp = accelVals.length();

View File

@@ -0,0 +1,175 @@
/*
Android_Pebble_sd - Android alarm client for openseizuredetector..
See http://openseizuredetector.org for more information.
Copyright Graham Jones, 2015, 2016
This file is part of pebble_sd.
Android_Pebble_sd is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Android_Pebble_sd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Android_pebble_sd. If not, see <http://www.gnu.org/licenses/>.
*/
package uk.org.openseizuredetector;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.util.Log;
import static java.lang.Math.sqrt;
/**
* A data source that uses the accelerometer built into the phone to provide seizure detector data for testing purposes.
* Note that this is unlikely to be useable as a viable seizure detector because the phone must be firmly attached to the part of the body that
* will shake during a seizure.
*/
public class SdDataSourcePhone extends SdDataSource implements SensorEventListener {
private String TAG = "SdDataSourcePhone";
private final static int NSAMP = 250;
private SensorManager mSensorManager;
private Sensor mSensor;
private int mMode = 0; // 0=check data rate, 1=running
private SensorEvent mStartEvent = null;
private long mStartTs = 0;
public double mSampleFreq = 0;
private PowerManager.WakeLock mWakeLock;
public SdDataSourcePhone(Context context, Handler handler,
SdDataReceiver sdDataReceiver) {
super(context, handler, sdDataReceiver);
mName = "Phone";
// Set default settings from XML files (mContext is set by super().
PreferenceManager.setDefaultValues(mContext,
R.xml.network_passive_datasource_prefs, true);
}
/**
* Start the datasource updating - initialises from sharedpreferences first to
* make sure any changes to preferences are taken into account.
*/
public void start() {
Log.i(TAG, "start()");
mUtil.writeToSysLogFile("SdDataSourcePhone.start()");
mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor , SensorManager.SENSOR_DELAY_GAME);
super.start();
}
/**
* Stop the datasource from updating
*/
public void stop() {
Log.i(TAG, "stop()");
mUtil.writeToSysLogFile("SdDataSourcePhone.stop()");
mSensorManager.unregisterListener(this);
super.stop();
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// we initially start in mMode=0, which calculates the sample frequency returned by the sensor, then enters mMode=1, which is normal operation.
if (mMode == 0) {
if (mStartEvent==null) {
Log.v(TAG,"onSensorChanged(): mMode=0 - checking Sample Rate - mNSamp = "+mSdData.mNsamp);
Log.v(TAG,"onSensorChanged(): saving initial event data");
mStartEvent = event;
mStartTs = event.timestamp;
mSdData.mNsamp = 0;
} else {
mSdData.mNsamp ++;
}
if (mSdData.mNsamp>=250) {
Log.v(TAG,"onSensorChanged(): Collected Data = final TimeStamp="+event.timestamp+", initial TimeStamp="+mStartTs);
double dT = 1e-9*(event.timestamp - mStartTs);
mSdData.mSampleFreq = (int)(mSdData.mNsamp/dT);
mSdData.haveSettings = true;
Log.v(TAG,"onSensorChanged(): Collected data for "+dT+" sec - calculated sample rate as "+ mSampleFreq +" Hz");
mMode = 1;
mSdData.mNsamp = 0;
mStartTs = event.timestamp;
}
} else if (mMode==1) {
// mMode=1 is normal operation - collect NSAMP accelerometer data samples, then analyse them by calling doAnalysis().
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
//Log.v(TAG,"Accelerometer Data Received: x="+x+", y="+y+", z="+z);
mSdData.rawData[mSdData.mNsamp] = sqrt(x*x + y*y + z*z);
mSdData.mNsamp++;
if (mSdData.mNsamp==NSAMP) {
// Calculate the sample frequency for this sample, but do not change mSampleFreq, which is used for
// analysis - this is because sometimes you get a very long delay (e.g. when disconnecting debugger),
// which gives a very low frequency which can make us run off the end of arrays in doAnalysis().
// FIXME - we should do some sort of check and disregard samples with long delays in them.
double dT = 1e-9*(event.timestamp - mStartTs);
int sampleFreq = (int)(mSdData.mNsamp/dT);
Log.v(TAG,"onSensorChanged(): Collected "+NSAMP+" data points in "+dT+" sec (="+sampleFreq+" Hz) - analysing...");
// DownSample from the 50Hz received frequency to 25Hz and convert to mg.
// FIXME - we should really do this properly rather than assume we are really receiving data at 50Hz.
for (int i=0; i<mSdData.mNsamp; i++) {
mSdData.rawData[i/2] = 1000.*mSdData.rawData[i]/9.81;
//Log.v(TAG,"i="+i+", rawData="+mSdData.rawData[i]+","+mSdData.rawData[i/2]);
}
mSdData.mNsamp /= 2;
doAnalysis();
mSdData.mNsamp = 0;
mStartTs = event.timestamp;
} else if (mSdData.mNsamp>NSAMP) {
Log.v(TAG,"onSensorChanged(): Received data during analysis - ignoring sample");
}
} else {
Log.v(TAG,"onSensorChanged(): ERROR - Mode "+mMode+" unrecognised");
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
Log.v(TAG,"onAccuracyChanged()");
}
}

View File

@@ -250,6 +250,11 @@ public class SdServer extends Service implements SdDataReceiver {
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourceBLE");
mSdDataSource = new SdDataSourceBLE(this.getApplicationContext(), mHandler, this);
break;
case "Phone":
Log.v(TAG, "Selecting Phone Sensor DataSource");
mUtil.writeToSysLogFile("SdServer.onStartCommand() - creating SdDataSourcePhone");
mSdDataSource = new SdDataSourcePhone(this.getApplicationContext(), mHandler, this);
break;
default:
Log.e(TAG, "Datasource " + mSdDataSourceName + " not recognised - Defaulting to Pebble");
mUtil.writeToSysLogFile("SdServer.onStartCommand() - Datasource " + mSdDataSourceName + " not recognised - exiting");

View File

@@ -1,16 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="datasource_list">
<item>"Pebble Watch"</item>
<item>"Garmin Watch"</item>
<item>"Network"</item>
<item>"Bluetooth Device"</item>
<item>"Pebble Watch"</item>
<item>"Phone Sensor (for testing)"</item>
<item>"Network (for Wifi Alerts)"</item>
</string-array>
<string-array name="datasource_list_values">
<item>"Pebble"</item>
<item>"Garmin"</item>
<item>"Network"</item>
<item>"BLE"</item>
<item>"Pebble"</item>
<item>"Phone"</item>
<item>"Network"</item>
</string-array>
</resources>

View File

@@ -2,6 +2,7 @@
<resources>
<string name="app_name">OpenSeizureDetector</string>
<string name="changelog">
\n V3.6 - Added phone sensor data source for testing without a watchs
\n V3.5 - Added support for Phone Call Alerts, using separate OpenSeizureDetector Dialler App
\n - Added Unique Identifier (UUID) to SMS alerts so they can be detected as OpenSeizureDetector SMS messages on client phone.
\n V3.4.0 - Aug 2020
@@ -143,6 +144,6 @@
<string name="menu_stop">STOP</string>
<string name="menu_scan">SCAN</string>
<string name="unknown_device">Unknown Device</string>
<string name="select_ble_device_title">Select BLE Device</string>
<string name="select_ble_device_desc">Select Bluetooth Low Energy (BLE) Device to provide seizure (acceleration and heart rate) data).</string>
<string name="select_ble_device_title">Select BLE Device (for Buetooth Data Source Only)</string>
<string name="select_ble_device_desc">Select Bluetooth Low Energy (BLE) Device to provide seizure (acceleration and heart rate) data) when using the Bluetooth Device data source.</string>
</resources>

View File

@@ -3,7 +3,7 @@
<ListPreference
android:key="DataSource"
android:title="Select Data Source"
android:summary="Select whether to use a Pebble Watch or network connection as the seizure detector data source."
android:summary="Select the seizure detector data source to use."
android:entries="@array/datasource_list"
android:entryValues="@array/datasource_list_values"
android:defaultValue="Garmin"