V4.1.0f - added V0.07 of CNN and added option to mark unverified events as false alarms

This commit is contained in:
Graham Jones
2022-09-26 21:06:39 +01:00
parent 726369c308
commit 45f2b0d5e9
9 changed files with 59 additions and 28 deletions

View File

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="uk.org.openseizuredetector" package="uk.org.openseizuredetector"
android:versionCode="108" android:versionCode="109"
android:versionName="4.1.0e"> android:versionName="4.1.0f">
<!-- android:allowBackup="false" --> <!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

Binary file not shown.

View File

@@ -458,6 +458,19 @@ public class LogManagerControlActivity extends AppCompatActivity {
}) })
.setNegativeButton(android.R.string.no, null) .setNegativeButton(android.R.string.no, null)
.show(); .show();
case R.id.action_mark_false_alarm:
Log.i(TAG, "action_mark_false_alarm");
new AlertDialog.Builder(this)
.setTitle(R.string.mark_unverified_events_false_alarm_dialog_title)
.setMessage(R.string.mark_unverified_events_false_alarm_dialog_message)
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mLm.mWac.markUnverifiedEventsAsFalseAlarm();
}
})
.setNegativeButton(android.R.string.no, null)
.show();
default: default:
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }

View File

@@ -25,7 +25,7 @@ import java.util.Map;
public class SdAlgNn { public class SdAlgNn {
private final static String TAG = "SdAlgNn"; private final static String TAG = "SdAlgNn";
private final static String MODEL_PATH = "best_model_v0.06.tflite"; private final static String MODEL_PATH = "best_model_v0.07.tflite";
private String mUrlBase = "https://osdApi.ddns.net"; private String mUrlBase = "https://osdApi.ddns.net";
private InterpreterApi interpreter; private InterpreterApi interpreter;
private Context mContext; private Context mContext;

View File

@@ -136,43 +136,46 @@ public abstract class WebApiConnection {
/** /**
* Mark all of the events with IDs contained in eventList as unknown type. * Mark all of the events with IDs contained in eventList as the specified type and subtype.
* @param eventList list of String IDs of the events to mark as unknown. * @param eventList list of String IDs of the events to mark as unknown.
* @param typeStr
* @param subTypeStr
* @return true if request sent successfully or false. * @return true if request sent successfully or false.
*/ */
private boolean markEventsAsUnknown(ArrayList<String>eventList) { private boolean markEventsAsTypeSubType(ArrayList<String>eventList, String typeStr, String subTypeStr) {
if (eventList.size()>0) { if (eventList.size()>0) {
Log.i(TAG,"markEventsAsUnknown - eventList.size()="+eventList.size()); Log.i(TAG,"markEventsAsTypeSubtype - eventList.size()="+eventList.size());
Log.i(TAG,"markEventsAsUnknown - eventList(0) = "+eventList.get(0)); Log.i(TAG,"markEventsAsSypeSubtype - eventList(0) = "+eventList.get(0));
getEvent(eventList.get(0), new WebApiConnection.JSONObjectCallback() { getEvent(eventList.get(0), new WebApiConnection.JSONObjectCallback() {
@Override @Override
public void accept(JSONObject eventObj) { public void accept(JSONObject eventObj) {
Log.v(TAG, "markEventsAsUnknown.getEvent.callback: "+eventObj); Log.v(TAG, "markEventsAsTypeSubtype.getEvent.callback: "+eventObj);
if (eventObj != null) { if (eventObj != null) {
Log.v(TAG, "markEventsAsUnknown.getEvent.callback: eventObj=" + eventObj.toString()); Log.v(TAG, "markEventsAsTypeSubtype.getEvent.callback: eventObj=" + eventObj.toString());
try { try {
eventObj.put("type", "Unknown"); eventObj.put("type", typeStr);
eventObj.put("subType", subTypeStr);
String notesStr = eventObj.getString("desc"); String notesStr = eventObj.getString("desc");
if (notesStr == null) notesStr = new String(""); if (notesStr == null) notesStr = new String("");
notesStr = notesStr + " Set to Unknown automatically by OSD Android App"; notesStr = notesStr + " bulk type/subtype set";
eventObj.put("desc", notesStr); eventObj.put("desc", notesStr);
updateEvent(eventObj,new WebApiConnection.JSONObjectCallback() { updateEvent(eventObj,new WebApiConnection.JSONObjectCallback() {
@Override @Override
public void accept(JSONObject eventObj) { public void accept(JSONObject eventObj) {
if (eventObj != null) { if (eventObj != null) {
Log.i(TAG, "markEventsAsUnknown.updateEvent.callback" + eventObj.toString()); Log.i(TAG, "markEventsAsTypeSubtype.updateEvent.callback" + eventObj.toString());
// Remove the first item from the list,then call this whole procedure again to modify the next one on the list. // Remove the first item from the list,then call this whole procedure again to modify the next one on the list.
eventList.remove(0); eventList.remove(0);
markEventsAsUnknown(eventList); markEventsAsTypeSubType(eventList, typeStr, subTypeStr);
} else { } else {
Log.e(TAG, "markEventsAsUnknown.updateEvent.callback - eventObj is null"); Log.e(TAG, "markEventsAsTypeSubtype.updateEvent.callback - eventObj is null");
mUtil.showToast("markEventsAsUnknown.updateEvent.callback - eventObj is null"); mUtil.showToast("markEventsAsTypeSubtype.updateEvent.callback - eventObj is null");
} }
} }
}); });
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG,"markEventsAsUnknown.getEvent.callback: Error editing eventObj"); Log.e(TAG,"markEventsAsTypeSubtype.getEvent.callback: Error editing eventObj");
mUtil.showToast("markEventsAsUnknown.getEvent.callback: Error editing eventObj"); mUtil.showToast("markEventsAsTypeSubtype.getEvent.callback: Error editing eventObj");
} }
} else { } else {
mUtil.showToast("Failed to Retrieve Event from Remote Database"); mUtil.showToast("Failed to Retrieve Event from Remote Database");
@@ -181,7 +184,7 @@ public abstract class WebApiConnection {
} }
}); });
} else { } else {
Log.i(TAG,"markEventsAsUnknown(): No more events to Modify"); Log.i(TAG,"markEventsAsTypeSubtype(): No more events to Modify");
mUtil.showToast("No more unvalidated events to modify."); mUtil.showToast("No more unvalidated events to modify.");
} }
@@ -193,37 +196,37 @@ public abstract class WebApiConnection {
* *
* @return true if request is successful or false. * @return true if request is successful or false.
*/ */
public boolean markUnverifiedEventsAsUnknown() { public boolean markUnverifiedEventsAsTypeSubtype(String typeStr, String subTypeStr) {
if (getEvents((JSONObject remoteEventsObj) -> { if (getEvents((JSONObject remoteEventsObj) -> {
Log.v(TAG, "markUnverifiedEventsAsUnknown.getEvents.Callback()"); Log.v(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents.Callback()");
Boolean haveUnvalidatedEvent = false; Boolean haveUnvalidatedEvent = false;
if (remoteEventsObj == null) { if (remoteEventsObj == null) {
Log.e(TAG, "markUnverifiedEventsAsUnknown.getEvents.Callback: Error Retrieving events"); Log.e(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents.Callback: Error Retrieving events");
} else { } else {
try { try {
JSONArray eventsArray = remoteEventsObj.getJSONArray("events"); JSONArray eventsArray = remoteEventsObj.getJSONArray("events");
ArrayList<String> unvalidatedEventsList = new ArrayList<String>(); ArrayList<String> unvalidatedEventsList = new ArrayList<String>();
for (int i = eventsArray.length() - 1; i >= 0; i--) { for (int i = eventsArray.length() - 1; i >= 0; i--) {
JSONObject eventObj = eventsArray.getJSONObject(i); JSONObject eventObj = eventsArray.getJSONObject(i);
String typeStr = eventObj.getString("type"); String currTypeStr = eventObj.getString("type");
if (typeStr.equals("null") || typeStr.equals("")) { if (currTypeStr.equals("null") || currTypeStr.equals("")) {
haveUnvalidatedEvent = true; haveUnvalidatedEvent = true;
unvalidatedEventsList.add(eventObj.getString("id")); unvalidatedEventsList.add(eventObj.getString("id"));
} }
} }
Log.v(TAG, "markUnverifiedEventsAsUnknown.getEvents.onFinish.callback - haveUnvalidatedEvent = " + Log.v(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents.onFinish.callback - haveUnvalidatedEvent = " +
haveUnvalidatedEvent); haveUnvalidatedEvent);
markEventsAsUnknown(unvalidatedEventsList); markEventsAsTypeSubType(unvalidatedEventsList, typeStr, subTypeStr);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(TAG, "markUnverifiedEventsAsUnknown.getEvents.onFinish(): Error Parsing remoteEventsObj: " + e.getMessage()); Log.e(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents.onFinish(): Error Parsing remoteEventsObj: " + e.getMessage());
//mUtil.showToast("Error Parsing remoteEventsObj - this should not happen!!!"); //mUtil.showToast("Error Parsing remoteEventsObj - this should not happen!!!");
} }
} }
})) { })) {
Log.v(TAG, "markUnverifiedEventsAsUnknown.getEvents - requested events"); Log.v(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents - requested events");
} else { } else {
Log.v(TAG, "markUnverifiedEventsAsUnknown.getEvents - Not Logged In"); Log.v(TAG, "markUnverifiedEventsAsTypeSubtype.getEvents - Not Logged In");
} }
@@ -231,4 +234,12 @@ public abstract class WebApiConnection {
return (true); return (true);
} }
public boolean markUnverifiedEventsAsUnknown() {
markUnverifiedEventsAsTypeSubtype("Unknown", "");
return true;
}
public boolean markUnverifiedEventsAsFalseAlarm() {
markUnverifiedEventsAsTypeSubtype("False Alarm", "");
return true;
}
} }

View File

@@ -9,6 +9,10 @@
android:id="@+id/action_mark_unknown" android:id="@+id/action_mark_unknown"
app:showAsAction="never|withText" app:showAsAction="never|withText"
android:title="@string/mark_unverified_events_as_unknown" /> android:title="@string/mark_unverified_events_as_unknown" />
<item
android:id="@+id/action_mark_false_alarm"
app:showAsAction="never|withText"
android:title="@string/mark_unverified_events_as_false_alarm" />
</group> </group>
<group android:id="@+id/grp3"> <group android:id="@+id/grp3">

View File

@@ -443,4 +443,7 @@
<string name="CnnAlarmEnabledTitle">Enable AI (Neural Network) Algorithm</string> <string name="CnnAlarmEnabledTitle">Enable AI (Neural Network) Algorithm</string>
<string name="CnnAlarmEnabledSummary">Enable the Artificial Intelligence (Neural Network) algorithm to generate alarms.</string> <string name="CnnAlarmEnabledSummary">Enable the Artificial Intelligence (Neural Network) algorithm to generate alarms.</string>
<string name="AlgorithmSelectionTitle">Seizure Detection Algorithms Selection</string> <string name="AlgorithmSelectionTitle">Seizure Detection Algorithms Selection</string>
<string name="mark_unverified_events_false_alarm_dialog_title">Mark all Unverified Events as False Alarm</string>
<string name="mark_unverified_events_false_alarm_dialog_message">Please confirm that all genuine seizure events have been verified before marking all unverified events as type \'False Alarm\'. \n\nContinue to mark unverified events as False Alarm?</string>
<string name="mark_unverified_events_as_false_alarm">Mark all Unverified Events as False Alarm</string>
</resources> </resources>