Started v2.0 of android app - re-factored so the service uses a datasource to populate the SdData class - so that we can make different data sources in the future.
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
build
|
||||||
|
.gradle
|
||||||
|
.idea
|
||||||
|
app/build
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
<content url="file://$MODULE_DIR$">
|
<content url="file://$MODULE_DIR$">
|
||||||
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Android_Pebble_SD_AS" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="Android_Pebble_SD" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
|
||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="android-gradle" name="Android-Gradle">
|
<facet type="android-gradle" name="Android-Gradle">
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="uk.org.openseizuredetector"
|
package="uk.org.openseizuredetector"
|
||||||
android:versionCode="16"
|
android:versionCode="17"
|
||||||
android:versionName="1.12">
|
android:versionName="2.0a">
|
||||||
<uses-sdk android:minSdkVersion="11" />
|
<uses-sdk android:minSdkVersion="11" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
|
|||||||
@@ -25,9 +25,7 @@
|
|||||||
|
|
||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
import android.app.ActionBar;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.IntentService;
|
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityManager.RunningServiceInfo;
|
import android.app.ActivityManager.RunningServiceInfo;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
@@ -35,22 +33,15 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.preference.Preference;
|
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.media.ToneGenerator;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.net.wifi.WifiManager;
|
|
||||||
import android.net.wifi.WifiInfo;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.os.RemoteException;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
@@ -58,7 +49,6 @@ import android.view.MenuItem;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewConfiguration;
|
import android.view.ViewConfiguration;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
@@ -69,28 +59,12 @@ import java.util.Enumeration;
|
|||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import org.apache.http.conn.util.InetAddressUtils;
|
import org.apache.http.conn.util.InetAddressUtils;
|
||||||
import java.lang.CharSequence;
|
|
||||||
import android.util.AttributeSet;
|
|
||||||
|
|
||||||
//MPAndroidChart
|
//MPAndroidChart
|
||||||
import com.github.mikephil.charting.charts.LineChart;
|
import com.github.mikephil.charting.charts.LineChart;
|
||||||
import com.github.mikephil.charting.components.Legend;
|
|
||||||
import com.github.mikephil.charting.components.Legend.LegendForm;
|
|
||||||
import com.github.mikephil.charting.components.LimitLine;
|
|
||||||
import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
|
|
||||||
import com.github.mikephil.charting.components.XAxis;
|
|
||||||
import com.github.mikephil.charting.components.YAxis;
|
|
||||||
import com.github.mikephil.charting.data.DataSet;
|
|
||||||
import com.github.mikephil.charting.data.Entry;
|
import com.github.mikephil.charting.data.Entry;
|
||||||
import com.github.mikephil.charting.data.LineData;
|
import com.github.mikephil.charting.data.LineData;
|
||||||
import com.github.mikephil.charting.data.LineDataSet;
|
import com.github.mikephil.charting.data.LineDataSet;
|
||||||
import com.github.mikephil.charting.data.filter.Approximator;
|
|
||||||
import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType;
|
|
||||||
import com.github.mikephil.charting.listener.OnChartGestureListener;
|
|
||||||
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
|
|
||||||
import com.github.mikephil.charting.utils.Highlight;
|
|
||||||
|
|
||||||
import uk.org.openseizuredetector.SdServer;
|
|
||||||
|
|
||||||
public class MainActivity extends Activity
|
public class MainActivity extends Activity
|
||||||
{
|
{
|
||||||
@@ -466,31 +440,31 @@ public class MainActivity extends Activity
|
|||||||
try {
|
try {
|
||||||
if (mBound) {
|
if (mBound) {
|
||||||
tv = (TextView) findViewById(R.id.alarmTv);
|
tv = (TextView) findViewById(R.id.alarmTv);
|
||||||
if ((mSdServer.sdData.alarmState==0)
|
if ((mSdServer.mSdData.alarmState==0)
|
||||||
&& !mSdServer.sdData.alarmStanding
|
&& !mSdServer.mSdData.alarmStanding
|
||||||
&& !mSdServer.sdData.fallAlarmStanding) {
|
&& !mSdServer.mSdData.fallAlarmStanding) {
|
||||||
tv.setText("OK");
|
tv.setText("OK");
|
||||||
tv.setBackgroundColor(okColour);
|
tv.setBackgroundColor(okColour);
|
||||||
}
|
}
|
||||||
if ((mSdServer.sdData.alarmState==1)
|
if ((mSdServer.mSdData.alarmState==1)
|
||||||
&& !mSdServer.sdData.alarmStanding
|
&& !mSdServer.mSdData.alarmStanding
|
||||||
&& !mSdServer.sdData.fallAlarmStanding) {
|
&& !mSdServer.mSdData.fallAlarmStanding) {
|
||||||
tv.setText("WARNING");
|
tv.setText("WARNING");
|
||||||
tv.setBackgroundColor(warnColour);
|
tv.setBackgroundColor(warnColour);
|
||||||
}
|
}
|
||||||
if (mSdServer.sdData.alarmStanding) {
|
if (mSdServer.mSdData.alarmStanding) {
|
||||||
tv.setText("**ALARM**");
|
tv.setText("**ALARM**");
|
||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
}
|
}
|
||||||
if (mSdServer.sdData.fallAlarmStanding) {
|
if (mSdServer.mSdData.fallAlarmStanding) {
|
||||||
tv.setText("**FALL**");
|
tv.setText("**FALL**");
|
||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
}
|
}
|
||||||
tv = (TextView) findViewById(R.id.pebTimeTv);
|
tv = (TextView) findViewById(R.id.pebTimeTv);
|
||||||
tv.setText(mSdServer.mPebbleStatusTime.format("%H:%M:%S"));
|
tv.setText(mSdServer.mSdData.dataTime.format("%H:%M:%S"));
|
||||||
// Pebble Connected Phrase
|
// Pebble Connected Phrase
|
||||||
tv = (TextView) findViewById(R.id.pebbleTv);
|
tv = (TextView) findViewById(R.id.pebbleTv);
|
||||||
if (mSdServer.sdData.pebbleConnected) {
|
if (mSdServer.mSdData.pebbleConnected) {
|
||||||
tv.setText("Pebble Watch Connected OK");
|
tv.setText("Pebble Watch Connected OK");
|
||||||
tv.setBackgroundColor(okColour);
|
tv.setBackgroundColor(okColour);
|
||||||
} else {
|
} else {
|
||||||
@@ -498,7 +472,7 @@ public class MainActivity extends Activity
|
|||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
}
|
}
|
||||||
tv = (TextView) findViewById(R.id.appTv);
|
tv = (TextView) findViewById(R.id.appTv);
|
||||||
if (mSdServer.sdData.pebbleAppRunning) {
|
if (mSdServer.mSdData.pebbleAppRunning) {
|
||||||
tv.setText("Pebble App OK");
|
tv.setText("Pebble App OK");
|
||||||
tv.setBackgroundColor(okColour);
|
tv.setBackgroundColor(okColour);
|
||||||
} else {
|
} else {
|
||||||
@@ -506,19 +480,19 @@ public class MainActivity extends Activity
|
|||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
}
|
}
|
||||||
tv = (TextView) findViewById(R.id.battTv);
|
tv = (TextView) findViewById(R.id.battTv);
|
||||||
tv.setText("Pebble Battery = "+String.valueOf(mSdServer.sdData.batteryPc)+"%");
|
tv.setText("Pebble Battery = "+String.valueOf(mSdServer.mSdData.batteryPc)+"%");
|
||||||
if (mSdServer.sdData.batteryPc<=20)
|
if (mSdServer.mSdData.batteryPc<=20)
|
||||||
tv.setBackgroundColor(alarmColour);
|
tv.setBackgroundColor(alarmColour);
|
||||||
if (mSdServer.sdData.batteryPc>20)
|
if (mSdServer.mSdData.batteryPc>20)
|
||||||
tv.setBackgroundColor(warnColour);
|
tv.setBackgroundColor(warnColour);
|
||||||
if (mSdServer.sdData.batteryPc>=40)
|
if (mSdServer.mSdData.batteryPc>=40)
|
||||||
tv.setBackgroundColor(okColour);
|
tv.setBackgroundColor(okColour);
|
||||||
|
|
||||||
tv = (TextView) findViewById(R.id.debugTv);
|
tv = (TextView) findViewById(R.id.debugTv);
|
||||||
String specStr = "";
|
String specStr = "";
|
||||||
for (int i=0;i<10;i++)
|
for (int i=0;i<10;i++)
|
||||||
specStr = specStr
|
specStr = specStr
|
||||||
+ mSdServer.sdData.simpleSpec[i]
|
+ mSdServer.mSdData.simpleSpec[i]
|
||||||
+ ", ";
|
+ ", ";
|
||||||
tv.setText("Spec = "+specStr);
|
tv.setText("Spec = "+specStr);
|
||||||
}
|
}
|
||||||
@@ -544,7 +518,7 @@ public class MainActivity extends Activity
|
|||||||
ArrayList<Entry> yVals = new ArrayList<Entry>();
|
ArrayList<Entry> yVals = new ArrayList<Entry>();
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
if (mSdServer!=null)
|
if (mSdServer!=null)
|
||||||
yVals.add(new Entry(mSdServer.sdData.simpleSpec[i], i));
|
yVals.add(new Entry(mSdServer.mSdData.simpleSpec[i], i));
|
||||||
else
|
else
|
||||||
yVals.add(new Entry(i, i));
|
yVals.add(new Entry(i, i));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class SdData implements Parcelable {
|
|||||||
jsonObj.put("dataTimeStr","00000000T000000");
|
jsonObj.put("dataTimeStr","00000000T000000");
|
||||||
jsonObj.put("dataTime","00-00-00 00:00:00");
|
jsonObj.put("dataTime","00-00-00 00:00:00");
|
||||||
}
|
}
|
||||||
Log.v(TAG,"sdData.dataTime = "+dataTime);
|
Log.v(TAG,"mSdData.dataTime = "+dataTime);
|
||||||
jsonObj.put("maxVal",maxVal);
|
jsonObj.put("maxVal",maxVal);
|
||||||
jsonObj.put("maxFreq",maxFreq);
|
jsonObj.put("maxFreq",maxFreq);
|
||||||
jsonObj.put("specPower",specPower);
|
jsonObj.put("specPower",specPower);
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
Android_Pebble_sd - Android alarm client for openseizuredetector..
|
||||||
|
|
||||||
|
See http://openseizuredetector.org for more information.
|
||||||
|
|
||||||
|
Copyright Graham Jones, 2015.
|
||||||
|
|
||||||
|
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.util.Log;
|
||||||
|
|
||||||
|
interface SdDataReceiver {
|
||||||
|
public void onSdDataReceived(SdData sdData);
|
||||||
|
public void onSdDataFault(SdData sdData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for a seizure detector data source. Subclasses include a pebble smart watch data source and a
|
||||||
|
* network data source.
|
||||||
|
*/
|
||||||
|
public abstract class SdDataSource {
|
||||||
|
public SdData mSdData;
|
||||||
|
protected Context mContext;
|
||||||
|
protected SdDataReceiver mSdDataReceiver;
|
||||||
|
private String TAG = "SdDataSource";
|
||||||
|
|
||||||
|
public SdDataSource(Context context, SdDataReceiver sdDataReceiver) {
|
||||||
|
Log.v(TAG, "SdDataSource() Constructor");
|
||||||
|
mContext = context;
|
||||||
|
mSdDataReceiver = sdDataReceiver;
|
||||||
|
mSdData = new SdData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the SdData object stored by this class.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SdData getSdData() {
|
||||||
|
return mSdData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the datasource updating - initialises from sharedpreferences first to
|
||||||
|
* make sure any changes to preferences are taken into account.
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
Log.v(TAG, "start()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the datasource from updating
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
Log.v(TAG, "stop()");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,441 @@
|
|||||||
|
/*
|
||||||
|
Android_Pebble_sd - Android alarm client for openseizuredetector..
|
||||||
|
|
||||||
|
See http://openseizuredetector.org for more information.
|
||||||
|
|
||||||
|
Copyright Graham Jones, 2015.
|
||||||
|
|
||||||
|
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.SharedPreferences;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
import android.text.format.Time;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.getpebble.android.kit.Constants;
|
||||||
|
import com.getpebble.android.kit.PebbleKit;
|
||||||
|
import com.getpebble.android.kit.util.PebbleDictionary;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.IntBuffer;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class for a seizure detector data source. Subclasses include a pebble smart watch data source and a
|
||||||
|
* network data source.
|
||||||
|
*/
|
||||||
|
public class SdDataSourcePebble extends SdDataSource {
|
||||||
|
private Timer mSettingsTimer;
|
||||||
|
private Timer mStatusTimer;
|
||||||
|
private Time mPebbleStatusTime;
|
||||||
|
private boolean mPebbleAppRunningCheck = false;
|
||||||
|
private int mAppRestartTimeout = 10; // Timeout before re-starting watch app (sec).
|
||||||
|
//private Looper mServiceLooper;
|
||||||
|
private int mFaultTimerPeriod = 30; // Fault Timer Period in sec
|
||||||
|
private PebbleKit.PebbleDataReceiver msgDataHandler = null;
|
||||||
|
|
||||||
|
|
||||||
|
private String TAG = "SdDataSourcePebble";
|
||||||
|
|
||||||
|
private UUID SD_UUID = UUID.fromString("03930f26-377a-4a3d-aa3e-f3b19e421c9d");
|
||||||
|
private int NSAMP = 512; // Number of samples in fft input dataset.
|
||||||
|
|
||||||
|
private int KEY_DATA_TYPE = 1;
|
||||||
|
private int KEY_ALARMSTATE = 2;
|
||||||
|
private int KEY_MAXVAL = 3;
|
||||||
|
private int KEY_MAXFREQ = 4;
|
||||||
|
private int KEY_SPECPOWER = 5;
|
||||||
|
private int KEY_SETTINGS = 6;
|
||||||
|
private int KEY_ALARM_FREQ_MIN = 7;
|
||||||
|
private int KEY_ALARM_FREQ_MAX = 8;
|
||||||
|
private int KEY_WARN_TIME = 9;
|
||||||
|
private int KEY_ALARM_TIME = 10;
|
||||||
|
private int KEY_ALARM_THRESH = 11;
|
||||||
|
private int KEY_POS_MIN = 12; // position of first data point in array
|
||||||
|
private int KEY_POS_MAX = 13; // position of last data point in array.
|
||||||
|
private int KEY_SPEC_DATA = 14; // Spectrum data
|
||||||
|
private int KEY_ROIPOWER = 15;
|
||||||
|
private int KEY_NMIN = 16;
|
||||||
|
private int KEY_NMAX = 17;
|
||||||
|
private int KEY_ALARM_RATIO_THRESH = 18;
|
||||||
|
private int KEY_BATTERY_PC = 19;
|
||||||
|
//private int KEY_SET_SETTINGS =20; // Phone is asking us to update watch app settings.
|
||||||
|
private int KEY_FALL_THRESH_MIN = 21;
|
||||||
|
private int KEY_FALL_THRESH_MAX = 22;
|
||||||
|
private int KEY_FALL_WINDOW = 23;
|
||||||
|
private int KEY_FALL_ACTIVE = 24;
|
||||||
|
|
||||||
|
// Values of the KEY_DATA_TYPE entry in a message
|
||||||
|
private int DATA_TYPE_RESULTS = 1; // Analysis Results
|
||||||
|
private int DATA_TYPE_SETTINGS = 2; // Settings
|
||||||
|
private int DATA_TYPE_SPEC = 3; // FFT Spectrum (or part of a spectrum)
|
||||||
|
|
||||||
|
public SdDataSourcePebble(Context context, SdDataReceiver sdDataReceiver) {
|
||||||
|
super(context,sdDataReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start the datasource updating - initialises from sharedpreferences first to
|
||||||
|
* make sure any changes to preferences are taken into account.
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
Log.v(TAG, "start()");
|
||||||
|
updatePrefs();
|
||||||
|
startPebbleServer();
|
||||||
|
// Start timer to check status of pebble regularly.
|
||||||
|
mPebbleStatusTime = new Time(Time.getCurrentTimezone());
|
||||||
|
//getPebbleStatus();
|
||||||
|
if (mStatusTimer == null) {
|
||||||
|
Log.v(TAG, "onCreate(): starting status timer");
|
||||||
|
mStatusTimer = new Timer();
|
||||||
|
mStatusTimer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getPebbleStatus();
|
||||||
|
}
|
||||||
|
}, 0, 1000);
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "onCreate(): status timer already running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start timer to retrieve pebble settings regularly.
|
||||||
|
getPebbleSdSettings();
|
||||||
|
if (mSettingsTimer == null) {
|
||||||
|
Log.v(TAG, "onCreate(): starting settings timer");
|
||||||
|
mSettingsTimer = new Timer();
|
||||||
|
mSettingsTimer.schedule(new TimerTask() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
getPebbleSdSettings();
|
||||||
|
}
|
||||||
|
}, 0, 1000 * 60);
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "onCreate(): settings timer already running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stop the datasource from updating
|
||||||
|
*/
|
||||||
|
public void stop() {
|
||||||
|
Log.v(TAG, "stop()");
|
||||||
|
try {
|
||||||
|
// Stop the status timer
|
||||||
|
if (mStatusTimer != null) {
|
||||||
|
Log.v(TAG, "onDestroy(): cancelling status timer");
|
||||||
|
mStatusTimer.cancel();
|
||||||
|
mStatusTimer.purge();
|
||||||
|
mStatusTimer = null;
|
||||||
|
}
|
||||||
|
// Stop the settings timer
|
||||||
|
if (mSettingsTimer != null) {
|
||||||
|
Log.v(TAG, "onDestroy(): cancelling settings timer");
|
||||||
|
mSettingsTimer.cancel();
|
||||||
|
mSettingsTimer.purge();
|
||||||
|
mSettingsTimer = null;
|
||||||
|
}
|
||||||
|
// Stop pebble message handler.
|
||||||
|
Log.v(TAG, "onDestroy(): stopping pebble server");
|
||||||
|
stopPebbleServer();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.v(TAG, "Error in stop() - " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* updatePrefs() - update basic settings from the SharedPreferences
|
||||||
|
* - defined in res/xml/SdDataSourcePebblePrefs.xml
|
||||||
|
*/
|
||||||
|
public void updatePrefs() {
|
||||||
|
Log.v(TAG, "updatePrefs()");
|
||||||
|
SharedPreferences SP = PreferenceManager
|
||||||
|
.getDefaultSharedPreferences(mContext);
|
||||||
|
try {
|
||||||
|
// Parse the AppRestartTimeout period setting.
|
||||||
|
try {
|
||||||
|
String appRestartTimeoutStr = SP.getString("AppRestartTimeout", "10");
|
||||||
|
mAppRestartTimeout = Integer.parseInt(appRestartTimeoutStr);
|
||||||
|
Log.v(TAG, "updatePrefs() - mAppRestartTimeout = " + mAppRestartTimeout);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.v(TAG, "updatePrefs() - Problem with AppRestartTimeout preference!");
|
||||||
|
Toast toast = Toast.makeText(mContext, "Problem Parsing AppRestartTimeout Preference", Toast.LENGTH_SHORT);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Parse the FaultTimer period setting.
|
||||||
|
try {
|
||||||
|
String faultTimerPeriodStr = SP.getString("FaultTimerPeriod", "30");
|
||||||
|
mFaultTimerPeriod = Integer.parseInt(faultTimerPeriodStr);
|
||||||
|
Log.v(TAG, "updatePrefs() - mFaultTimerPeriod = " + mFaultTimerPeriod);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.v(TAG, "updatePrefs() - Problem with FaultTimerPeriod preference!");
|
||||||
|
Toast toast = Toast.makeText(mContext, "Problem Parsing FaultTimerPeriod Preference", Toast.LENGTH_SHORT);
|
||||||
|
toast.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Watch Settings
|
||||||
|
PebbleDictionary setDict = new PebbleDictionary();
|
||||||
|
short intVal;
|
||||||
|
String prefStr;
|
||||||
|
prefStr = SP.getString("AlarmFreqMin", "5");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + intVal);
|
||||||
|
setDict.addInt16(KEY_ALARM_FREQ_MIN, intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("AlarmFreqMax", "10");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + intVal);
|
||||||
|
setDict.addUint16(KEY_ALARM_FREQ_MAX, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("WarnTime", "5");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() WarnTime = " + intVal);
|
||||||
|
setDict.addUint16(KEY_WARN_TIME, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("AlarmTime", "10");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() AlarmTime = " + intVal);
|
||||||
|
setDict.addUint16(KEY_ALARM_TIME, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("AlarmThresh", "100");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() AlarmThresh = " + intVal);
|
||||||
|
setDict.addUint16(KEY_ALARM_THRESH, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("AlarmRatioThresh", "30");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + intVal);
|
||||||
|
setDict.addUint16(KEY_ALARM_RATIO_THRESH, (short) intVal);
|
||||||
|
|
||||||
|
boolean fallActiveBool = SP.getBoolean("FallActive", false);
|
||||||
|
Log.v(TAG, "updatePrefs() FallActive = " + fallActiveBool);
|
||||||
|
if (fallActiveBool)
|
||||||
|
setDict.addUint16(KEY_FALL_ACTIVE, (short) 1);
|
||||||
|
else
|
||||||
|
setDict.addUint16(KEY_FALL_ACTIVE, (short) 0);
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallThreshMin", "200");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallThreshMin = " + intVal);
|
||||||
|
setDict.addUint16(KEY_FALL_THRESH_MIN, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallThreshMax", "1200");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallThreshMax = " + intVal);
|
||||||
|
setDict.addUint16(KEY_FALL_THRESH_MAX, (short) intVal);
|
||||||
|
|
||||||
|
prefStr = SP.getString("FallWindow", "1500");
|
||||||
|
intVal = (short) Integer.parseInt(prefStr);
|
||||||
|
Log.v(TAG, "updatePrefs() FallWindow = " + intVal);
|
||||||
|
setDict.addUint16(KEY_FALL_WINDOW, (short) intVal);
|
||||||
|
|
||||||
|
|
||||||
|
// Send Watch Settings to Pebble
|
||||||
|
Log.v(TAG, "updatePrefs() - setDict = " + setDict.toJsonString());
|
||||||
|
PebbleKit.sendDataToPebble(mContext, SD_UUID, setDict);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this server to receive pebble data by registering it as
|
||||||
|
* A PebbleDataReceiver
|
||||||
|
*/
|
||||||
|
private void startPebbleServer() {
|
||||||
|
Log.v(TAG, "StartPebbleServer()");
|
||||||
|
final Handler handler = new Handler();
|
||||||
|
msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) {
|
||||||
|
@Override
|
||||||
|
public void receiveData(final Context context,
|
||||||
|
final int transactionId,
|
||||||
|
final PebbleDictionary data) {
|
||||||
|
Log.v(TAG, "Received message from Pebble - data type="
|
||||||
|
+ data.getUnsignedIntegerAsLong(KEY_DATA_TYPE));
|
||||||
|
// If we ha ve a message, the app must be running
|
||||||
|
mPebbleAppRunningCheck = true;
|
||||||
|
PebbleKit.sendAckToPebble(context, transactionId);
|
||||||
|
//Log.v(TAG,"Message is: "+data.toJsonString());
|
||||||
|
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
||||||
|
== DATA_TYPE_RESULTS) {
|
||||||
|
Log.v(TAG, "DATA_TYPE = Results");
|
||||||
|
mSdData.dataTime.setToNow();
|
||||||
|
Log.v(TAG, "mSdData.dataTime=" + mSdData.dataTime);
|
||||||
|
|
||||||
|
mSdData.alarmState = data.getUnsignedIntegerAsLong(
|
||||||
|
KEY_ALARMSTATE);
|
||||||
|
mSdData.maxVal = data.getUnsignedIntegerAsLong(KEY_MAXVAL);
|
||||||
|
mSdData.maxFreq = data.getUnsignedIntegerAsLong(KEY_MAXFREQ);
|
||||||
|
mSdData.specPower = data.getUnsignedIntegerAsLong(KEY_SPECPOWER);
|
||||||
|
mSdData.roiPower = data.getUnsignedIntegerAsLong(KEY_ROIPOWER);
|
||||||
|
mSdData.alarmPhrase = "Unknown";
|
||||||
|
mSdDataReceiver.onSdDataReceived(mSdData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Read the data that has been sent, and convert it into
|
||||||
|
// an integer array.
|
||||||
|
byte[] byteArr = data.getBytes(KEY_SPEC_DATA);
|
||||||
|
if ((byteArr!=null) && (byteArr.length!=0)) {
|
||||||
|
IntBuffer intBuf = ByteBuffer.wrap(byteArr)
|
||||||
|
.order(ByteOrder.LITTLE_ENDIAN)
|
||||||
|
.asIntBuffer();
|
||||||
|
int[] intArray = new int[intBuf.remaining()];
|
||||||
|
intBuf.get(intArray);
|
||||||
|
for (int i = 0; i < intArray.length; i++) {
|
||||||
|
mSdData.simpleSpec[i] = intArray[i];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.v(TAG,"***** zero length spectrum received - error!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
||||||
|
== DATA_TYPE_SETTINGS) {
|
||||||
|
Log.v(TAG, "DATA_TYPE = Settings");
|
||||||
|
mSdData.alarmFreqMin = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MIN);
|
||||||
|
mSdData.alarmFreqMax = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MAX);
|
||||||
|
mSdData.nMin = data.getUnsignedIntegerAsLong(KEY_NMIN);
|
||||||
|
mSdData.nMax = data.getUnsignedIntegerAsLong(KEY_NMAX);
|
||||||
|
mSdData.warnTime = data.getUnsignedIntegerAsLong(KEY_WARN_TIME);
|
||||||
|
mSdData.alarmTime = data.getUnsignedIntegerAsLong(KEY_ALARM_TIME);
|
||||||
|
mSdData.alarmThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_THRESH);
|
||||||
|
mSdData.alarmRatioThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_RATIO_THRESH);
|
||||||
|
mSdData.batteryPc = data.getUnsignedIntegerAsLong(KEY_BATTERY_PC);
|
||||||
|
mSdData.haveSettings = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
PebbleKit.registerReceivedDataHandler(mContext, msgDataHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* De-register this server from receiving pebble data
|
||||||
|
*/
|
||||||
|
public void stopPebbleServer() {
|
||||||
|
Log.v(TAG, "stopPebbleServer(): Stopping Pebble Server");
|
||||||
|
Log.v(TAG, "stopPebbleServer(): msgDataHandler = " + msgDataHandler.toString());
|
||||||
|
try {
|
||||||
|
mContext.unregisterReceiver(msgDataHandler);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.v(TAG, "stopPebbleServer() - error " + e.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to start the pebble_sd watch app on the pebble watch.
|
||||||
|
*/
|
||||||
|
public void startWatchApp() {
|
||||||
|
PebbleKit.startAppOnPebble(mContext, SD_UUID);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* stop the pebble_sd watch app on the pebble watch.
|
||||||
|
*/
|
||||||
|
public void stopWatchApp() {
|
||||||
|
PebbleKit.closeAppOnPebble(mContext, SD_UUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request Pebble App to send us its latest settings.
|
||||||
|
* Will be received as a message by the receiveData handler
|
||||||
|
*/
|
||||||
|
public void getPebbleSdSettings() {
|
||||||
|
Log.v(TAG, "getPebbleSdSettings() - requesting settings from pebble");
|
||||||
|
PebbleDictionary data = new PebbleDictionary();
|
||||||
|
data.addUint8(KEY_SETTINGS, (byte) 1);
|
||||||
|
PebbleKit.sendDataToPebble(
|
||||||
|
mContext,
|
||||||
|
SD_UUID,
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the status of the connection to the pebble watch,
|
||||||
|
* and sets class variables for use by other functions.
|
||||||
|
* If the watch app is not running, it attempts to re-start it.
|
||||||
|
*/
|
||||||
|
public void getPebbleStatus() {
|
||||||
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
|
long tdiff;
|
||||||
|
tnow.setToNow();
|
||||||
|
tdiff = (tnow.toMillis(false) - mPebbleStatusTime.toMillis(false));
|
||||||
|
// Check we are actually connected to the pebble.
|
||||||
|
mSdData.pebbleConnected = PebbleKit.isWatchConnected(mContext);
|
||||||
|
// And is the pebble_sd app running?
|
||||||
|
// set mPebbleAppRunningCheck has been false for more than 10 seconds
|
||||||
|
// the app is not talking to us
|
||||||
|
// mPebbleAppRunningCheck is set to true in the receiveData handler.
|
||||||
|
if (!mPebbleAppRunningCheck &&
|
||||||
|
(tdiff > mAppRestartTimeout * 1000)) {
|
||||||
|
Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff);
|
||||||
|
mSdData.pebbleAppRunning = false;
|
||||||
|
Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
|
||||||
|
startWatchApp();
|
||||||
|
getPebbleSdSettings();
|
||||||
|
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
|
||||||
|
if (tdiff > mFaultTimerPeriod * 1000) {
|
||||||
|
mSdDataReceiver.onSdDataFault(mSdData);
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "getPebbleStatus() - Waiting for mFaultTimerPeriod before issuing audible warning...");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mSdData.pebbleAppRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have confirmation that the app is running, reset the
|
||||||
|
// status time to now and initiate another check.
|
||||||
|
if (mPebbleAppRunningCheck) {
|
||||||
|
mPebbleAppRunningCheck = false;
|
||||||
|
mPebbleStatusTime.setToNow();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mSdData.haveSettings) {
|
||||||
|
Log.v(TAG, "getPebbleStatus() - no settings received yet - requesting");
|
||||||
|
getPebbleSdSettings();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -27,11 +27,9 @@
|
|||||||
package uk.org.openseizuredetector;
|
package uk.org.openseizuredetector;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import fi.iki.elonen.NanoHTTPD;
|
import fi.iki.elonen.NanoHTTPD;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.ActivityManager.RunningServiceInfo;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -39,46 +37,31 @@ import android.app.Service;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.AssetFileDescriptor;
|
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.ToneGenerator;
|
import android.media.ToneGenerator;
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.os.Handler;
|
|
||||||
import android.os.HandlerThread;
|
import android.os.HandlerThread;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.CountDownTimer;
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Looper;
|
|
||||||
import android.os.Message;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
import android.os.Process;
|
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.telephony.SmsManager;
|
import android.telephony.SmsManager;
|
||||||
import android.telephony.SmsMessage;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.net.URL;
|
|
||||||
import android.net.Uri;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ShortBuffer;
|
|
||||||
import java.nio.IntBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import android.text.format.Time;
|
import android.text.format.Time;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
|
||||||
import com.getpebble.android.kit.Constants;
|
|
||||||
import com.getpebble.android.kit.PebbleKit;
|
|
||||||
import com.getpebble.android.kit.util.PebbleDictionary;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,41 +70,7 @@ import com.getpebble.android.kit.util.PebbleDictionary;
|
|||||||
* and
|
* and
|
||||||
* http://developer.android.com/guide/components/services.html#ExtendingService
|
* http://developer.android.com/guide/components/services.html#ExtendingService
|
||||||
*/
|
*/
|
||||||
public class SdServer extends Service
|
public class SdServer extends Service implements SdDataReceiver {
|
||||||
{
|
|
||||||
private UUID SD_UUID = UUID.fromString("03930f26-377a-4a3d-aa3e-f3b19e421c9d");
|
|
||||||
private int NSAMP = 512; // Number of samples in fft input dataset.
|
|
||||||
|
|
||||||
private int KEY_DATA_TYPE = 1;
|
|
||||||
private int KEY_ALARMSTATE = 2;
|
|
||||||
private int KEY_MAXVAL = 3;
|
|
||||||
private int KEY_MAXFREQ = 4;
|
|
||||||
private int KEY_SPECPOWER = 5;
|
|
||||||
private int KEY_SETTINGS = 6;
|
|
||||||
private int KEY_ALARM_FREQ_MIN =7;
|
|
||||||
private int KEY_ALARM_FREQ_MAX =8;
|
|
||||||
private int KEY_WARN_TIME = 9;
|
|
||||||
private int KEY_ALARM_TIME = 10;
|
|
||||||
private int KEY_ALARM_THRESH = 11;
|
|
||||||
private int KEY_POS_MIN = 12; // position of first data point in array
|
|
||||||
private int KEY_POS_MAX = 13; // position of last data point in array.
|
|
||||||
private int KEY_SPEC_DATA = 14; // Spectrum data
|
|
||||||
private int KEY_ROIPOWER = 15;
|
|
||||||
private int KEY_NMIN = 16;
|
|
||||||
private int KEY_NMAX = 17;
|
|
||||||
private int KEY_ALARM_RATIO_THRESH = 18;
|
|
||||||
private int KEY_BATTERY_PC = 19;
|
|
||||||
//private int KEY_SET_SETTINGS =20; // Phone is asking us to update watch app settings.
|
|
||||||
private int KEY_FALL_THRESH_MIN = 21;
|
|
||||||
private int KEY_FALL_THRESH_MAX = 22;
|
|
||||||
private int KEY_FALL_WINDOW = 23;
|
|
||||||
private int KEY_FALL_ACTIVE =24;
|
|
||||||
|
|
||||||
// Values of the KEY_DATA_TYPE entry in a message
|
|
||||||
private int DATA_TYPE_RESULTS = 1; // Analysis Results
|
|
||||||
private int DATA_TYPE_SETTINGS = 2; // Settings
|
|
||||||
private int DATA_TYPE_SPEC = 3; // FFT Spectrum (or part of a spectrum)
|
|
||||||
|
|
||||||
// Notification ID
|
// Notification ID
|
||||||
private int NOTIFICATION_ID = 1;
|
private int NOTIFICATION_ID = 1;
|
||||||
|
|
||||||
@@ -129,18 +78,11 @@ public class SdServer extends Service
|
|||||||
|
|
||||||
private WebServer webServer = null;
|
private WebServer webServer = null;
|
||||||
private final static String TAG = "SdServer";
|
private final static String TAG = "SdServer";
|
||||||
private Looper mServiceLooper;
|
|
||||||
public Time mPebbleStatusTime;
|
|
||||||
private boolean mPebbleAppRunningCheck = false;
|
|
||||||
private Timer statusTimer = null;
|
|
||||||
private int mFaultTimerPeriod = 30; // Fault Timer Period in sec
|
|
||||||
private int mAppRestartTimeout = 10; // Timeout before re-starting watch app (sec).
|
|
||||||
private Timer settingsTimer = null;
|
|
||||||
private Timer dataLogTimer = null;
|
private Timer dataLogTimer = null;
|
||||||
private HandlerThread thread;
|
private HandlerThread thread;
|
||||||
private WakeLock mWakeLock = null;
|
private WakeLock mWakeLock = null;
|
||||||
public SdData sdData;
|
public SdDataSource mSdDataSource;
|
||||||
private PebbleKit.PebbleDataReceiver msgDataHandler = null;
|
public SdData mSdData;
|
||||||
private boolean mLatchAlarms = false;
|
private boolean mLatchAlarms = false;
|
||||||
private boolean mCancelAudible = false;
|
private boolean mCancelAudible = false;
|
||||||
private boolean mAudibleAlarm = false;
|
private boolean mAudibleAlarm = false;
|
||||||
@@ -158,7 +100,7 @@ public class SdServer extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* class to handle binding the MainApp activity to this service
|
* class to handle binding the MainApp activity to this service
|
||||||
* so it can access sdData.
|
* so it can access mSdData.
|
||||||
*/
|
*/
|
||||||
public class SdBinder extends Binder {
|
public class SdBinder extends Binder {
|
||||||
SdServer getService() {
|
SdServer getService() {
|
||||||
@@ -171,7 +113,7 @@ public class SdServer extends Service
|
|||||||
*/
|
*/
|
||||||
public SdServer() {
|
public SdServer() {
|
||||||
super();
|
super();
|
||||||
sdData = new SdData();
|
mSdData = new SdData();
|
||||||
Log.v(TAG, "SdServer Created");
|
Log.v(TAG, "SdServer Created");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +125,6 @@ public class SdServer extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onCreate() - called when services is created. Starts message
|
* onCreate() - called when services is created. Starts message
|
||||||
* handler process to listen for messages from other processes.
|
* handler process to listen for messages from other processes.
|
||||||
@@ -192,6 +133,7 @@ public class SdServer extends Service
|
|||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
Log.v(TAG, "onCreate()");
|
Log.v(TAG, "onCreate()");
|
||||||
|
|
||||||
|
|
||||||
// Create a wake lock, but don't use it until the service is started.
|
// Create a wake lock, but don't use it until the service is started.
|
||||||
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
|
||||||
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
|
||||||
@@ -209,6 +151,9 @@ public class SdServer extends Service
|
|||||||
// Update preferences.
|
// Update preferences.
|
||||||
Log.v(TAG, "onStartCommand() - calling updatePrefs()");
|
Log.v(TAG, "onStartCommand() - calling updatePrefs()");
|
||||||
updatePrefs();
|
updatePrefs();
|
||||||
|
mSdDataSource = new SdDataSourcePebble(this.getApplicationContext(), this);
|
||||||
|
mSdDataSource.start();
|
||||||
|
|
||||||
|
|
||||||
// Display a notification icon in the status bar of the phone to
|
// Display a notification icon in the status bar of the phone to
|
||||||
// show the service is running.
|
// show the service is running.
|
||||||
@@ -220,35 +165,6 @@ public class SdServer extends Service
|
|||||||
mSMSTime = new Time(Time.getCurrentTimezone());
|
mSMSTime = new Time(Time.getCurrentTimezone());
|
||||||
|
|
||||||
|
|
||||||
// Start receiving data from the pebble watch
|
|
||||||
startPebbleServer();
|
|
||||||
|
|
||||||
// Start timer to check status of pebble regularly.
|
|
||||||
mPebbleStatusTime = new Time(Time.getCurrentTimezone());
|
|
||||||
//getPebbleStatus();
|
|
||||||
if (statusTimer==null) {
|
|
||||||
Log.v(TAG,"onCreate(): starting status timer");
|
|
||||||
statusTimer = new Timer();
|
|
||||||
statusTimer.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {getPebbleStatus();}
|
|
||||||
}, 0, 1000);
|
|
||||||
} else {
|
|
||||||
Log.v(TAG,"onCreate(): status timer already running.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start timer to retrieve pebble settings regularly.
|
|
||||||
getPebbleSdSettings();
|
|
||||||
if (settingsTimer == null) {
|
|
||||||
Log.v(TAG,"onCreate(): starting settings timer");
|
|
||||||
settingsTimer = new Timer();
|
|
||||||
settingsTimer.schedule(new TimerTask() {
|
|
||||||
@Override
|
|
||||||
public void run() {getPebbleSdSettings();}
|
|
||||||
}, 0, 1000*60);
|
|
||||||
} else {
|
|
||||||
Log.v(TAG,"onCreate(): settings timer already running.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start timer to log data regularly..
|
// Start timer to log data regularly..
|
||||||
if (dataLogTimer == null) {
|
if (dataLogTimer == null) {
|
||||||
@@ -256,7 +172,9 @@ public class SdServer extends Service
|
|||||||
dataLogTimer = new Timer();
|
dataLogTimer = new Timer();
|
||||||
dataLogTimer.schedule(new TimerTask() {
|
dataLogTimer.schedule(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {logData();}
|
public void run() {
|
||||||
|
logData();
|
||||||
|
}
|
||||||
}, 0, 1000 * 60);
|
}, 0, 1000 * 60);
|
||||||
} else {
|
} else {
|
||||||
Log.v(TAG, "onCreate(): dataLog timer already running.");
|
Log.v(TAG, "onCreate(): dataLog timer already running.");
|
||||||
@@ -289,30 +207,15 @@ public class SdServer extends Service
|
|||||||
Log.d(TAG, "mmm...mWakeLock is null, so not releasing lock. This shouldn't happen!");
|
Log.d(TAG, "mmm...mWakeLock is null, so not releasing lock. This shouldn't happen!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSdDataSource.stop();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Stop the status timer
|
|
||||||
if (statusTimer!=null) {
|
|
||||||
Log.v(TAG,"onDestroy(): cancelling status timer");
|
|
||||||
statusTimer.cancel();
|
|
||||||
statusTimer.purge();
|
|
||||||
statusTimer = null;
|
|
||||||
}
|
|
||||||
// Stop the settings timer
|
|
||||||
if (settingsTimer!=null) {
|
|
||||||
Log.v(TAG,"onDestroy(): cancelling settings timer");
|
|
||||||
settingsTimer.cancel();
|
|
||||||
settingsTimer.purge();
|
|
||||||
settingsTimer = null;
|
|
||||||
}
|
|
||||||
// Cancel the notification.
|
// Cancel the notification.
|
||||||
Log.v(TAG, "onDestroy(): cancelling notification");
|
Log.v(TAG, "onDestroy(): cancelling notification");
|
||||||
mNM.cancel(NOTIFICATION_ID);
|
mNM.cancel(NOTIFICATION_ID);
|
||||||
// Stop web server
|
// Stop web server
|
||||||
Log.v(TAG, "onDestroy(): stopping web server");
|
Log.v(TAG, "onDestroy(): stopping web server");
|
||||||
stopWebServer();
|
stopWebServer();
|
||||||
// Stop pebble message handler.
|
|
||||||
Log.v(TAG,"onDestroy(): stopping pebble server");
|
|
||||||
stopPebbleServer();
|
|
||||||
// stop this service.
|
// stop this service.
|
||||||
Log.v(TAG, "onDestroy(): calling stopSelf()");
|
Log.v(TAG, "onDestroy(): calling stopSelf()");
|
||||||
stopSelf();
|
stopSelf();
|
||||||
@@ -323,7 +226,6 @@ public class SdServer extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a notification while this service is running.
|
* Show a notification while this service is running.
|
||||||
*/
|
*/
|
||||||
@@ -343,122 +245,12 @@ public class SdServer extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* from http://stackoverflow.com/questions/12154940/how-to-make-a-beep-in-android */
|
|
||||||
/**
|
/**
|
||||||
* beep for duration miliseconds, but only if mAudibleAlarm is set.
|
* Process the data received from the SdData source.
|
||||||
|
* @param sdData
|
||||||
*/
|
*/
|
||||||
private void beep(int duration) {
|
public void onSdDataReceived(SdData sdData) {
|
||||||
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
|
Log.v(TAG, "onSdDataReceived()");
|
||||||
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, duration);
|
|
||||||
Log.v(TAG,"beep()");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* beep, provided mAudibleAlarm is set
|
|
||||||
*/
|
|
||||||
public void faultWarningBeep() {
|
|
||||||
if (mCancelAudible) {
|
|
||||||
Log.v(TAG, "faultWarningBeep() - CancelAudible Active - silent beep...");
|
|
||||||
} else {
|
|
||||||
if (mAudibleFaultWarning) {
|
|
||||||
beep(10);
|
|
||||||
Log.v(TAG, "faultWarningBeep()");
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "faultWarningBeep() - silent...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* beep, provided mAudibleAlarm is set
|
|
||||||
*/
|
|
||||||
public void alarmBeep() {
|
|
||||||
if (mCancelAudible) {
|
|
||||||
Log.v(TAG,"alarmBeep() - CancelAudible Active - silent beep...");
|
|
||||||
} else {
|
|
||||||
if (mAudibleAlarm) {
|
|
||||||
beep(1000);
|
|
||||||
Log.v(TAG,"alarmBeep()");
|
|
||||||
} else {
|
|
||||||
Log.v(TAG,"alarmBeep() - silent...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* beep, provided mAudibleWarning is set
|
|
||||||
*/
|
|
||||||
public void warningBeep() {
|
|
||||||
if (mCancelAudible) {
|
|
||||||
Log.v(TAG,"warningBeep() - CancelAudible Active - silent beep...");
|
|
||||||
} else {
|
|
||||||
if (mAudibleWarning) {
|
|
||||||
beep(100);
|
|
||||||
Log.v(TAG,"warningBeep()");
|
|
||||||
} else {
|
|
||||||
Log.v(TAG,"warningBeep() - silent...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends SMS Alarms to the telephone numbers specified in mSMSNumbers[]
|
|
||||||
*/
|
|
||||||
public void sendSMSAlarm() {
|
|
||||||
if (mSMSAlarm) {
|
|
||||||
Log.v(TAG,"sendSMSAlarm() - Sending to "+mSMSNumbers.length+" Numbers");
|
|
||||||
Time tnow = new Time(Time.getCurrentTimezone());
|
|
||||||
tnow.setToNow();
|
|
||||||
String dateStr = tnow.format("%Y-%m-%d %H-%M-%S");
|
|
||||||
SmsManager sm = SmsManager.getDefault();
|
|
||||||
for (int i=0;i<mSMSNumbers.length;i++) {
|
|
||||||
Log.v(TAG,"sendSMSAlarm() - Sending to "+mSMSNumbers[i]);
|
|
||||||
sm.sendTextMessage(mSMSNumbers[i], null, mSMSMsgStr+" - "+dateStr, null, null);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Log.v(TAG,"sendSMSAlarm() - SMS Alarms Disabled - not doing anything!");
|
|
||||||
Toast toast = Toast.makeText(getApplicationContext(),
|
|
||||||
"SMS Alarms Disabled - not doing anything!",
|
|
||||||
Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set this server to receive pebble data by registering it as
|
|
||||||
* A PebbleDataReceiver
|
|
||||||
*/
|
|
||||||
private void startPebbleServer() {
|
|
||||||
Log.v(TAG, "StartPebbleServer()");
|
|
||||||
final Handler handler = new Handler();
|
|
||||||
msgDataHandler = new PebbleKit.PebbleDataReceiver(SD_UUID) {
|
|
||||||
@Override
|
|
||||||
public void receiveData(final Context context,
|
|
||||||
final int transactionId,
|
|
||||||
final PebbleDictionary data) {
|
|
||||||
Log.v(TAG, "Received message from Pebble - data type="
|
|
||||||
+ data.getUnsignedIntegerAsLong(KEY_DATA_TYPE));
|
|
||||||
// If we ha ve a message, the app must be running
|
|
||||||
mPebbleAppRunningCheck = true;
|
|
||||||
PebbleKit.sendAckToPebble(context, transactionId);
|
|
||||||
//Log.v(TAG,"Message is: "+data.toJsonString());
|
|
||||||
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
|
||||||
== DATA_TYPE_RESULTS) {
|
|
||||||
Log.v(TAG, "DATA_TYPE = Results");
|
|
||||||
sdData.dataTime.setToNow();
|
|
||||||
Log.v(TAG, "sdData.dataTime=" + sdData.dataTime);
|
|
||||||
|
|
||||||
sdData.alarmState = data.getUnsignedIntegerAsLong(
|
|
||||||
KEY_ALARMSTATE);
|
|
||||||
sdData.maxVal = data.getUnsignedIntegerAsLong(KEY_MAXVAL);
|
|
||||||
sdData.maxFreq = data.getUnsignedIntegerAsLong(KEY_MAXFREQ);
|
|
||||||
sdData.specPower = data.getUnsignedIntegerAsLong(KEY_SPECPOWER);
|
|
||||||
sdData.roiPower = data.getUnsignedIntegerAsLong(KEY_ROIPOWER);
|
|
||||||
sdData.alarmPhrase = "Unknown";
|
|
||||||
if (sdData.alarmState == 0) {
|
if (sdData.alarmState == 0) {
|
||||||
if ((!mLatchAlarms) ||
|
if ((!mLatchAlarms) ||
|
||||||
(mLatchAlarms &&
|
(mLatchAlarms &&
|
||||||
@@ -534,78 +326,110 @@ public class SdServer extends Service
|
|||||||
mSMSTime = tnow;
|
mSMSTime = tnow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
mSdData = sdData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onSdDataFault(SdData sdData) {
|
||||||
|
Log.v(TAG,"onSdDataFault()");
|
||||||
|
if (mAudibleFaultWarning) {
|
||||||
|
faultWarningBeep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* from http://stackoverflow.com/questions/12154940/how-to-make-a-beep-in-android */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* beep for duration miliseconds, but only if mAudibleAlarm is set.
|
||||||
|
*/
|
||||||
|
private void beep(int duration) {
|
||||||
|
ToneGenerator toneG = new ToneGenerator(AudioManager.STREAM_ALARM, 100);
|
||||||
|
toneG.startTone(ToneGenerator.TONE_CDMA_ALERT_CALL_GUARD, duration);
|
||||||
|
Log.v(TAG, "beep()");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* beep, provided mAudibleAlarm is set
|
||||||
|
*/
|
||||||
|
public void faultWarningBeep() {
|
||||||
|
if (mCancelAudible) {
|
||||||
|
Log.v(TAG, "faultWarningBeep() - CancelAudible Active - silent beep...");
|
||||||
|
} else {
|
||||||
|
if (mAudibleFaultWarning) {
|
||||||
|
beep(10);
|
||||||
|
Log.v(TAG, "faultWarningBeep()");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "faultWarningBeep() - silent...");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Read the data that has been sent, and convert it into
|
/*
|
||||||
// an integer array.
|
* beep, provided mAudibleAlarm is set
|
||||||
byte[] byteArr = data.getBytes(KEY_SPEC_DATA);
|
*/
|
||||||
IntBuffer intBuf = ByteBuffer.wrap(byteArr)
|
public void alarmBeep() {
|
||||||
.order(ByteOrder.LITTLE_ENDIAN)
|
if (mCancelAudible) {
|
||||||
.asIntBuffer();
|
Log.v(TAG, "alarmBeep() - CancelAudible Active - silent beep...");
|
||||||
int[] intArray = new int[intBuf.remaining()];
|
} else {
|
||||||
intBuf.get(intArray);
|
if (mAudibleAlarm) {
|
||||||
for (int i=0;i<intArray.length;i++) {
|
beep(1000);
|
||||||
sdData.simpleSpec[i] = intArray[i];
|
Log.v(TAG, "alarmBeep()");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "alarmBeep() - silent...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* beep, provided mAudibleWarning is set
|
||||||
|
*/
|
||||||
|
public void warningBeep() {
|
||||||
|
if (mCancelAudible) {
|
||||||
|
Log.v(TAG, "warningBeep() - CancelAudible Active - silent beep...");
|
||||||
|
} else {
|
||||||
|
if (mAudibleWarning) {
|
||||||
|
beep(100);
|
||||||
|
Log.v(TAG, "warningBeep()");
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "warningBeep() - silent...");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends SMS Alarms to the telephone numbers specified in mSMSNumbers[]
|
||||||
|
*/
|
||||||
|
public void sendSMSAlarm() {
|
||||||
|
if (mSMSAlarm) {
|
||||||
|
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers.length + " Numbers");
|
||||||
|
Time tnow = new Time(Time.getCurrentTimezone());
|
||||||
|
tnow.setToNow();
|
||||||
|
String dateStr = tnow.format("%Y-%m-%d %H-%M-%S");
|
||||||
|
SmsManager sm = SmsManager.getDefault();
|
||||||
|
for (int i = 0; i < mSMSNumbers.length; i++) {
|
||||||
|
Log.v(TAG, "sendSMSAlarm() - Sending to " + mSMSNumbers[i]);
|
||||||
|
sm.sendTextMessage(mSMSNumbers[i], null, mSMSMsgStr + " - " + dateStr, null, null);
|
||||||
}
|
}
|
||||||
if (data.getUnsignedIntegerAsLong(KEY_DATA_TYPE)
|
} else {
|
||||||
==DATA_TYPE_SETTINGS) {
|
Log.v(TAG, "sendSMSAlarm() - SMS Alarms Disabled - not doing anything!");
|
||||||
Log.v(TAG,"DATA_TYPE = Settings");
|
Toast toast = Toast.makeText(getApplicationContext(),
|
||||||
sdData.alarmFreqMin = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MIN);
|
"SMS Alarms Disabled - not doing anything!",
|
||||||
sdData.alarmFreqMax = data.getUnsignedIntegerAsLong(KEY_ALARM_FREQ_MAX);
|
Toast.LENGTH_SHORT);
|
||||||
sdData.nMin = data.getUnsignedIntegerAsLong(KEY_NMIN);
|
toast.show();
|
||||||
sdData.nMax = data.getUnsignedIntegerAsLong(KEY_NMAX);
|
|
||||||
sdData.warnTime = data.getUnsignedIntegerAsLong(KEY_WARN_TIME);
|
|
||||||
sdData.alarmTime = data.getUnsignedIntegerAsLong(KEY_ALARM_TIME);
|
|
||||||
sdData.alarmThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_THRESH);
|
|
||||||
sdData.alarmRatioThresh = data.getUnsignedIntegerAsLong(KEY_ALARM_RATIO_THRESH);
|
|
||||||
sdData.batteryPc = data.getUnsignedIntegerAsLong(KEY_BATTERY_PC);
|
|
||||||
sdData.haveSettings = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
PebbleKit.registerReceivedDataHandler(this,msgDataHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set the alarm standing flags to false to allow alarm phase to reset to current value.
|
* set the alarm standing flags to false to allow alarm phase to reset to current value.
|
||||||
*/
|
*/
|
||||||
public void acceptAlarm() {
|
public void acceptAlarm() {
|
||||||
Log.v(TAG, "acceptAlarm()");
|
Log.v(TAG, "acceptAlarm()");
|
||||||
sdData.alarmStanding = false;
|
mSdData.alarmStanding = false;
|
||||||
sdData.fallAlarmStanding = false;
|
mSdData.fallAlarmStanding = false;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* De-register this server from receiving pebble data
|
|
||||||
*/
|
|
||||||
public void stopPebbleServer() {
|
|
||||||
Log.v(TAG,"stopPebbleServer(): Stopping Pebble Server");
|
|
||||||
Log.v(TAG,"stopPebbleServer(): msgDataHandler = "+msgDataHandler.toString());
|
|
||||||
try {
|
|
||||||
unregisterReceiver(msgDataHandler);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.v(TAG,"stopPebbleServer() - error "+e.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Attempt to start the pebble_sd watch app on the pebble watch.
|
|
||||||
*/
|
|
||||||
public void startWatchApp() {
|
|
||||||
PebbleKit.startAppOnPebble(getApplicationContext(),
|
|
||||||
SD_UUID);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* stop the pebble_sd watch app on the pebble watch.
|
|
||||||
*/
|
|
||||||
public void stopWatchApp() {
|
|
||||||
PebbleKit.closeAppOnPebble(getApplicationContext(),
|
|
||||||
SD_UUID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -653,68 +477,6 @@ public class SdServer extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks the status of the connection to the pebble watch,
|
|
||||||
* and sets class variables for use by other functions.
|
|
||||||
* If the watch app is not running, it attempts to re-start it.
|
|
||||||
*/
|
|
||||||
public void getPebbleStatus() {
|
|
||||||
Time tnow = new Time(Time.getCurrentTimezone());
|
|
||||||
long tdiff;
|
|
||||||
tnow.setToNow();
|
|
||||||
tdiff = (tnow.toMillis(false) - mPebbleStatusTime.toMillis(false));
|
|
||||||
// Check we are actually connected to the pebble.
|
|
||||||
sdData.pebbleConnected = PebbleKit.isWatchConnected(this);
|
|
||||||
// And is the pebble_sd app running?
|
|
||||||
// set mPebbleAppRunningCheck has been false for more than 10 seconds
|
|
||||||
// the app is not talking to us
|
|
||||||
// mPebbleAppRunningCheck is set to true in the receiveData handler.
|
|
||||||
if (!mPebbleAppRunningCheck &&
|
|
||||||
(tdiff > mAppRestartTimeout * 1000)) {
|
|
||||||
Log.v(TAG, "getPebbleStatus() - tdiff = " + tdiff);
|
|
||||||
sdData.pebbleAppRunning = false;
|
|
||||||
Log.v(TAG, "getPebbleStatus() - Pebble App Not Running - Attempting to Re-Start");
|
|
||||||
startWatchApp();
|
|
||||||
getPebbleSdSettings();
|
|
||||||
// Only make audible warning beep if we have not received data for more than mFaultTimerPeriod seconds.
|
|
||||||
if ((tdiff > mFaultTimerPeriod * 1000)
|
|
||||||
&& (mAudibleFaultWarning)
|
|
||||||
) {
|
|
||||||
faultWarningBeep();
|
|
||||||
} else {
|
|
||||||
Log.v(TAG, "getPebbleStatus() - Waiting for mFaultTimerPeriod before issuing audible warning...");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sdData.pebbleAppRunning = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if we have confirmation that the app is running, reset the
|
|
||||||
// status time to now and initiate another check.
|
|
||||||
if (mPebbleAppRunningCheck) {
|
|
||||||
mPebbleAppRunningCheck = false;
|
|
||||||
mPebbleStatusTime.setToNow();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sdData.haveSettings) {
|
|
||||||
Log.v(TAG, "getPebbleStatus() - no settings received yet - requesting");
|
|
||||||
getPebbleSdSettings();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request Pebble App to send us its latest settings.
|
|
||||||
* Will be received as a message by the receiveData handler
|
|
||||||
*/
|
|
||||||
public void getPebbleSdSettings() {
|
|
||||||
Log.v(TAG,"getPebbleSdSettings() - requesting settings from pebble");
|
|
||||||
PebbleDictionary data = new PebbleDictionary();
|
|
||||||
data.addUint8(KEY_SETTINGS, (byte)1);
|
|
||||||
PebbleKit.sendDataToPebble(
|
|
||||||
getApplicationContext(),
|
|
||||||
SD_UUID,
|
|
||||||
data);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* updatePrefs() - update basic settings from the SharedPreferences
|
* updatePrefs() - update basic settings from the SharedPreferences
|
||||||
@@ -745,90 +507,6 @@ public class SdServer extends Service
|
|||||||
mLogData = SP.getBoolean("LogData", false);
|
mLogData = SP.getBoolean("LogData", false);
|
||||||
Log.v(TAG, "updatePrefs() - mLogData = " + mLogData);
|
Log.v(TAG, "updatePrefs() - mLogData = " + mLogData);
|
||||||
|
|
||||||
// Parse the AppRestartTimeout period setting.
|
|
||||||
try {
|
|
||||||
String appRestartTimeoutStr = SP.getString("AppRestartTimeout", "10");
|
|
||||||
mAppRestartTimeout = Integer.parseInt(appRestartTimeoutStr);
|
|
||||||
Log.v(TAG, "onStart() - mAppRestartTimeout = " + mAppRestartTimeout);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.v(TAG, "onStart() - Problem with AppRestartTimeout preference!");
|
|
||||||
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing AppRestartTimeout Preference", Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Parse the FaultTimer period setting.
|
|
||||||
try {
|
|
||||||
String faultTimerPeriodStr = SP.getString("FaultTimerPeriod", "30");
|
|
||||||
mFaultTimerPeriod = Integer.parseInt(faultTimerPeriodStr);
|
|
||||||
Log.v(TAG, "onStart() - mFaultTimerPeriod = " + mFaultTimerPeriod);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
Log.v(TAG, "onStart() - Problem with FaultTimerPeriod preference!");
|
|
||||||
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing FaultTimerPeriod Preference", Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Watch Settings
|
|
||||||
PebbleDictionary setDict = new PebbleDictionary();
|
|
||||||
short intVal;
|
|
||||||
String prefStr;
|
|
||||||
prefStr = SP.getString("AlarmFreqMin","5");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() AlarmFreqMin = " + intVal);
|
|
||||||
setDict.addInt16(KEY_ALARM_FREQ_MIN,intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmFreqMax","10");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() AlarmFreqMax = " + intVal);
|
|
||||||
setDict.addUint16(KEY_ALARM_FREQ_MAX, (short) intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("WarnTime","5");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() WarnTime = " + intVal);
|
|
||||||
setDict.addUint16(KEY_WARN_TIME,(short)intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmTime","10");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() AlarmTime = " + intVal);
|
|
||||||
setDict.addUint16(KEY_ALARM_TIME,(short)intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmThresh","100");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() AlarmThresh = " + intVal);
|
|
||||||
setDict.addUint16(KEY_ALARM_THRESH,(short)intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("AlarmRatioThresh","30");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG, "updatePrefs() AlarmRatioThresh = " + intVal);
|
|
||||||
setDict.addUint16(KEY_ALARM_RATIO_THRESH, (short) intVal);
|
|
||||||
|
|
||||||
boolean fallActiveBool = SP.getBoolean("FallActive",false);
|
|
||||||
Log.v(TAG, "updatePrefs() FallActive = " + fallActiveBool);
|
|
||||||
if (fallActiveBool)
|
|
||||||
setDict.addUint16(KEY_FALL_ACTIVE,(short)1);
|
|
||||||
else
|
|
||||||
setDict.addUint16(KEY_FALL_ACTIVE,(short)0);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallThreshMin","200");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG,"updatePrefs() FallThreshMin = "+intVal);
|
|
||||||
setDict.addUint16(KEY_FALL_THRESH_MIN,(short)intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallThreshMax","1200");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG,"updatePrefs() FallThreshMax = "+intVal);
|
|
||||||
setDict.addUint16(KEY_FALL_THRESH_MAX,(short)intVal);
|
|
||||||
|
|
||||||
prefStr = SP.getString("FallWindow","1500");
|
|
||||||
intVal = (short)Integer.parseInt(prefStr);
|
|
||||||
Log.v(TAG,"updatePrefs() FallWindow = "+intVal);
|
|
||||||
setDict.addUint16(KEY_FALL_WINDOW,(short)intVal);
|
|
||||||
|
|
||||||
|
|
||||||
// Send Watch Settings to Pebble
|
|
||||||
Log.v(TAG,"updatePrefs() - setDict = "+setDict.toJsonString());
|
|
||||||
PebbleKit.sendDataToPebble(getApplicationContext(), SD_UUID, setDict);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
Log.v(TAG, "updatePrefs() - Problem parsing preferences!");
|
||||||
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
Toast toast = Toast.makeText(getApplicationContext(), "Problem Parsing Preferences - Something won't work - Please go back to Settings and correct it!", Toast.LENGTH_SHORT);
|
||||||
@@ -894,9 +572,9 @@ public class SdServer extends Service
|
|||||||
try {
|
try {
|
||||||
FileWriter of = new FileWriter(getDataStorageDir().toString()
|
FileWriter of = new FileWriter(getDataStorageDir().toString()
|
||||||
+ "/" + fname, true);
|
+ "/" + fname, true);
|
||||||
if (sdData!=null) {
|
if (mSdData != null) {
|
||||||
Log.v(TAG,"writing sdData.toString()");
|
Log.v(TAG, "writing mSdData.toString()");
|
||||||
of.append(sdData.toString()+"\n");
|
of.append(mSdData.toString() + "\n");
|
||||||
}
|
}
|
||||||
of.close();
|
of.close();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
@@ -913,8 +591,8 @@ public class SdServer extends Service
|
|||||||
*/
|
*/
|
||||||
private class WebServer extends NanoHTTPD {
|
private class WebServer extends NanoHTTPD {
|
||||||
private String TAG = "WebServer";
|
private String TAG = "WebServer";
|
||||||
public WebServer()
|
|
||||||
{
|
public WebServer() {
|
||||||
// Set the port to listen on (8080)
|
// Set the port to listen on (8080)
|
||||||
super(8080);
|
super(8080);
|
||||||
}
|
}
|
||||||
@@ -939,17 +617,7 @@ public class SdServer extends Service
|
|||||||
case "/data":
|
case "/data":
|
||||||
//Log.v(TAG,"WebServer.serve() - Returning data");
|
//Log.v(TAG,"WebServer.serve() - Returning data");
|
||||||
try {
|
try {
|
||||||
//JSONObject jsonObj = new JSONObject();
|
answer = mSdData.toString();
|
||||||
//jsonObj.put("Time",mPebbleStatusTime.format("%H:%M:%S"));
|
|
||||||
//jsonObj.put("alarmState",sdData.alarmState);
|
|
||||||
//jsonObj.put("alarmPhrase",sdData.alarmPhrase);
|
|
||||||
//jsonObj.put("maxVal",sdData.maxVal);
|
|
||||||
//jsonObj.put("maxFreq",sdData.maxFreq);
|
|
||||||
//jsonObj.put("specPower",sdData.specPower);
|
|
||||||
//jsonObj.put("roiPower",sdData.roiPower);
|
|
||||||
//jsonObj.put("pebCon",mPebbleConnected);
|
|
||||||
//jsonObj.put("pebAppRun",mPebbleAppRunning);
|
|
||||||
answer = sdData.toString();
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
|
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
|
||||||
answer = "Error Creating Data Object";
|
answer = "Error Creating Data Object";
|
||||||
@@ -960,15 +628,15 @@ public class SdServer extends Service
|
|||||||
//Log.v(TAG,"WebServer.serve() - Returning settings");
|
//Log.v(TAG,"WebServer.serve() - Returning settings");
|
||||||
try {
|
try {
|
||||||
JSONObject jsonObj = new JSONObject();
|
JSONObject jsonObj = new JSONObject();
|
||||||
jsonObj.put("alarmFreqMin",sdData.alarmFreqMin);
|
jsonObj.put("alarmFreqMin", mSdData.alarmFreqMin);
|
||||||
jsonObj.put("alarmFreqMax",sdData.alarmFreqMax);
|
jsonObj.put("alarmFreqMax", mSdData.alarmFreqMax);
|
||||||
jsonObj.put("nMin",sdData.nMin);
|
jsonObj.put("nMin", mSdData.nMin);
|
||||||
jsonObj.put("nMax",sdData.nMax);
|
jsonObj.put("nMax", mSdData.nMax);
|
||||||
jsonObj.put("warnTime",sdData.warnTime);
|
jsonObj.put("warnTime", mSdData.warnTime);
|
||||||
jsonObj.put("alarmTime",sdData.alarmTime);
|
jsonObj.put("alarmTime", mSdData.alarmTime);
|
||||||
jsonObj.put("alarmThresh",sdData.alarmThresh);
|
jsonObj.put("alarmThresh", mSdData.alarmThresh);
|
||||||
jsonObj.put("alarmRatioThresh",sdData.alarmRatioThresh);
|
jsonObj.put("alarmRatioThresh", mSdData.alarmRatioThresh);
|
||||||
jsonObj.put("batteryPc",sdData.batteryPc);
|
jsonObj.put("batteryPc", mSdData.batteryPc);
|
||||||
answer = jsonObj.toString();
|
answer = jsonObj.toString();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
|
Log.v(TAG, "Error Creating Data Object - " + ex.toString());
|
||||||
@@ -981,10 +649,10 @@ public class SdServer extends Service
|
|||||||
try {
|
try {
|
||||||
JSONObject jsonObj = new JSONObject();
|
JSONObject jsonObj = new JSONObject();
|
||||||
Log.v(TAG, "WebServer.serve() - Returning spectrum - 2");
|
Log.v(TAG, "WebServer.serve() - Returning spectrum - 2");
|
||||||
// Initialised it this way because one phone was ok with JSONArray(sdData.simpleSpec), and the other crashed...
|
// Initialised it this way because one phone was ok with JSONArray(mSdData.simpleSpec), and the other crashed...
|
||||||
JSONArray arr = new JSONArray();
|
JSONArray arr = new JSONArray();
|
||||||
for (int i=0;i<sdData.simpleSpec.length;i++) {
|
for (int i = 0; i < mSdData.simpleSpec.length; i++) {
|
||||||
arr.put(sdData.simpleSpec[i]);
|
arr.put(mSdData.simpleSpec[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.v(TAG, "WebServer.serve() - Returning spectrum - 3");
|
Log.v(TAG, "WebServer.serve() - Returning spectrum - 3");
|
||||||
@@ -1006,8 +674,7 @@ public class SdServer extends Service
|
|||||||
uri.startsWith("/img/")) {
|
uri.startsWith("/img/")) {
|
||||||
//Log.v(TAG,"Serving File");
|
//Log.v(TAG,"Serving File");
|
||||||
return serveFile(uri);
|
return serveFile(uri);
|
||||||
}
|
} else if (uri.startsWith("/logs")) {
|
||||||
else if (uri.startsWith("/logs")) {
|
|
||||||
Log.v(TAG, "WebServer.serve() - serving data logs - uri=" + uri);
|
Log.v(TAG, "WebServer.serve() - serving data logs - uri=" + uri);
|
||||||
NanoHTTPD.Response resp = serveLogFile(uri);
|
NanoHTTPD.Response resp = serveLogFile(uri);
|
||||||
Log.v(TAG, "WebServer.serve() - response = " + resp.toString());
|
Log.v(TAG, "WebServer.serve() - response = " + resp.toString());
|
||||||
@@ -1023,8 +690,6 @@ public class SdServer extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a file from the external storage folder
|
* Return a file from the external storage folder
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user