From 4c3eee145439e942cc640fb1b955c353bd69008d Mon Sep 17 00:00:00 2001 From: Graham Jones Date: Sun, 10 Apr 2022 20:46:55 +0100 Subject: [PATCH] Sorting out issues with IDs being assumed to be Long integers, and fixed problem with duplicate event uploads for manual alarm events. --- .../EditEventActivity.java | 16 ++- .../org/openseizuredetector/LogManager.java | 111 ++++++++++-------- .../LogManagerControlActivity.java | 14 +-- .../uk/org/openseizuredetector/OsdUtil.java | 26 ++++ .../openseizuredetector/WebApiConnection.java | 4 +- .../WebApiConnection_osdapi.java | 32 ++--- 6 files changed, 123 insertions(+), 80 deletions(-) diff --git a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java index ab14fab..ccdc01e 100644 --- a/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/EditEventActivity.java @@ -200,17 +200,23 @@ public class EditEventActivity extends AppCompatActivity { tv = (TextView) findViewById(R.id.eventIdTv); tv.setText(mEventId); tv = (TextView) findViewById(R.id.eventAlarmStateTv); - tv.setText(mEventObj.getString("osdAlarmState")); + String alarmStateStr = mEventObj.getString("osdAlarmState"); + try { + int alarmStateVal = Integer.parseInt(alarmStateStr); + alarmStateStr = mUtil.alarmStatusToString(alarmStateVal); + } catch (Exception e) { + Log.v(TAG,"updateUi: alarmState does not parse to int so displaying it as string: " +alarmStateStr); + } + tv.setText(alarmStateStr); tv = (TextView) findViewById(R.id.eventNotsTv); tv.setText(mEventObj.getString("desc")); tv = (TextView) findViewById(R.id.eventDateTv); try { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - //Date dataTime = dateFormat.parse(mEventObj.getString("dataTime")); - Date dataTime = new Date(mEventObj.getLong("dataTime")); - dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String dateStr = mEventObj.getString("dataTime"); + Date dataTime = mUtil.string2date(dateStr); + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); tv.setText(dateFormat.format(dataTime)); } catch (Exception e) { Log.e(TAG,"updateUI: Error Parsing dataDate "+e.getLocalizedMessage()); diff --git a/app/src/main/java/uk/org/openseizuredetector/LogManager.java b/app/src/main/java/uk/org/openseizuredetector/LogManager.java index b14401c..2f905b3 100644 --- a/app/src/main/java/uk/org/openseizuredetector/LogManager.java +++ b/app/src/main/java/uk/org/openseizuredetector/LogManager.java @@ -763,10 +763,17 @@ public class LogManager { //int eventId = -1; //Log.v(TAG, "uploadSdData()"); // First try uploading full alarms, and only if we do not have any of those, upload warnings. - boolean warningsArr[] = {false, true}; + //boolean warningsArr[] = {false, true}; + // Upload everything - alarms and warnings - we can sort it out in post-processing the data! + boolean warningsArr[] = {true}; for (int n = 0; n < warningsArr.length; n++) { boolean warningsVal = warningsArr[n]; Log.i(TAG, "uploadSdData(): warningsVal=" + warningsVal); + if (mUploadInProgress) { + Log.d(TAG, "uploadSdData - upload already in progress - not doing anything"); + return; + } + mUploadInProgress = true; getNextEventToUpload(warningsVal, (Long eventId) -> { if (eventId != -1) { Log.i(TAG, "uploadSdData() - next Event to Upload eventId=" + eventId); @@ -782,7 +789,7 @@ public class LogManager { eventObj = datapointJsonArr.getJSONObject(0); // We only look at the first (and hopefully only) item in the array. eventAlarmStatus = Integer.parseInt(eventObj.getString("status")); eventDateStr = eventObj.getString("dataTime"); - Log.v(TAG, "uploadSdData - data from local DB is:" + eventJsonStr + ", eventAlarmStatus=" + Log.d(TAG, "uploadSdData - data from local DB is:" + eventJsonStr + ", eventAlarmStatus=" + eventAlarmStatus + ", eventDateStr=" + eventDateStr); } catch (JSONException e) { Log.e(TAG, "uploadSdData(): ERROR parsing event JSON Data" + eventJsonStr); @@ -805,6 +812,7 @@ public class LogManager { mWac.createEvent(eventAlarmStatus, eventDate, "", this::createEventCallback); } else { Log.v(TAG, "uploadSdData - no data to upload "); //(warnings="+warningsVal+")"); + mUploadInProgress = false; } }); } @@ -830,52 +838,61 @@ public class LogManager { mWac.getEvent(eventId, new WebApiConnection.JSONObjectCallback() { @Override public void accept(JSONObject eventObj) { - Log.v(TAG,"createEventCallback() - eventObj="+eventObj.toString()); - Date eventDate; - String eventDateStr = ""; - try { - Long eventTimestamp = eventObj.getLong("dataTime"); - eventDate = new Date(eventTimestamp); - eventDateStr = eventDate.toString(); - } catch (JSONException e) { - Log.e(TAG, "createEventCallback() - Error parsing JSONObject: " + eventObj.toString()); - finishUpload(); - return; + if (eventObj == null) { + Log.e(TAG,"createEventCallback() - eventObj is null - failed to create event"); + mUtil.showToast("Error Creating Remote Event"); + } else { + Log.v(TAG, "createEventCallback() - eventObj=" + eventObj.toString()); + Date eventDate; + String eventDateStr = ""; + try { + String dateStr= eventObj.getString("dataTime"); + eventDate = mUtil.string2date(dateStr); + } catch (JSONException e) { + Log.e(TAG, "createEventCallback() - Error parsing JSONObject: " + eventObj.toString()); + finishUpload(); + return; + } + if (eventDate != null) { + Log.v(TAG, "createEventCallback() EventId=" + eventId + ", eventDateStr=" + eventDateStr + ", eventDate=" + eventDate); + mUploadInProgress = true; + long eventDateMillis = eventDate.getTime(); + long startDateMillis = eventDateMillis - 1000 * mEventDuration / 2; + long endDateMillis = eventDateMillis + 1000 * mEventDuration / 2; + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + getDatapointsByDate( + dateFormat.format(new Date(startDateMillis)), + dateFormat.format(new Date(endDateMillis)), + (String datapointsJsonStr) -> { + //Log.v(TAG, "createEventCallback() - datapointsJsonStr=" + datapointsJsonStr); + JSONArray dataObj; + mDatapointsToUploadList = new ArrayList(); + try { + //DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + dataObj = new JSONArray(datapointsJsonStr); + Log.v(TAG, "createEventCallback() - datapointsObj length=" + dataObj.length()); + for (int i = 0; i < dataObj.length(); i++) { + mDatapointsToUploadList.add(dataObj.getJSONObject(i)); + } + } catch (JSONException e) { + Log.v(TAG, "createEventCallback(): Error Creating JSON Object from string " + datapointsJsonStr); + dataObj = null; + finishUpload(); + } + // This starts the process of uploading the datapoints, one at a time. + mCurrentEventRemoteId = eventId; + Log.v(TAG, "createEventCallback() - starting datapoints upload with eventId " + mCurrentEventRemoteId + + " Uploading " + mDatapointsToUploadList.size() + " datapoints"); + uploadNextDatapoint(); + + }); + } else { + Log.e(TAG,"createEventCallback() - Error - event date is null - not doing anything"); + mUtil.showToast("Error uploading event - date is null"); + finishUpload(); + } } - Log.v(TAG, "createEventCallback() EventId=" + eventId + ", eventDateStr=" + eventDateStr + ", eventDate=" + eventDate); - long eventDateMillis = eventDate.getTime(); - long startDateMillis = eventDateMillis - 1000 * mEventDuration / 2; - long endDateMillis = eventDateMillis + 1000 * mEventDuration / 2; - DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - - getDatapointsByDate( - dateFormat.format(new Date(startDateMillis)), - dateFormat.format(new Date(endDateMillis)), - (String datapointsJsonStr) -> { - //Log.v(TAG, "createEventCallback() - datapointsJsonStr=" + datapointsJsonStr); - JSONArray dataObj; - mDatapointsToUploadList = new ArrayList(); - try { - //DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - dataObj = new JSONArray(datapointsJsonStr); - Log.v(TAG, "createEventCallback() - datapointsObj length="+dataObj.length()); - for (int i = 0; i < dataObj.length(); i++) { - mDatapointsToUploadList.add(dataObj.getJSONObject(i)); - } - } catch (JSONException e) { - Log.v(TAG, "createEventCallback(): Error Creating JSON Object from string " + datapointsJsonStr); - dataObj = null; - finishUpload(); - } - // This starts the process of uploading the datapoints, one at a time. - mCurrentEventRemoteId = eventId; - mUploadInProgress = true; - Log.v(TAG, "createEventCallback() - starting datapoints upload with eventId " + mCurrentEventRemoteId + - " Uploading "+mDatapointsToUploadList.size()+" datapoints"); - uploadNextDatapoint(); - - }); - } }); } diff --git a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java index 1986e75..a7eb350 100644 --- a/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java +++ b/app/src/main/java/uk/org/openseizuredetector/LogManagerControlActivity.java @@ -625,18 +625,8 @@ public class LogManagerControlActivity extends AppCompatActivity { // Convert date format to something more readable. TextView tv = (TextView) v.findViewById(R.id.event_date_remote_tv); Date dataTime = null; - try { - Long tstamp = Long.parseLong((String) dataItem.get("dataTime")); - dataTime = new Date(tstamp); - } catch (NumberFormatException e) { - Log.v(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate as Long: " + e.getLocalizedMessage()+" trying as string"); - try { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); - dataTime = dateFormat.parse(dataItem.get("dataTime").toString()); - } catch (ParseException e2) { - Log.e(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate " + e2.getLocalizedMessage()); - } - } + String dateStr = (String) dataItem.get("dataTime"); + dataTime = mUtil.string2date(dateStr); if (dataTime != null) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss"); tv.setText(dateFormat.format(dataTime)); diff --git a/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java index 469a2d8..972e053 100644 --- a/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java +++ b/app/src/main/java/uk/org/openseizuredetector/OsdUtil.java @@ -59,6 +59,7 @@ import java.io.File; import java.io.FileWriter; import java.net.InetAddress; import java.net.NetworkInterface; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; @@ -453,6 +454,31 @@ public class OsdUtil { } } + /** + * string2date - returns a Date object represented by string dateStr + * It first attempts to parse it as a long integer, in which case it is assumed to + * be a unix timestamp. + * If that fails it attempts to parse it as yyyy-MM-dd'T'HH:mm:ss'Z' format. + * @param dateStr String reprenting a date + * @return Date object or null if parsing fails. + */ + public Date string2date(String dateStr) { + Date dataTime = null; + try { + Long tstamp = Long.parseLong(dateStr); + dataTime = new Date(tstamp); + } catch (NumberFormatException e) { + Log.v(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate as Long: " + e.getLocalizedMessage()+" trying as string"); + try { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); + dataTime = dateFormat.parse(dateStr); + } catch (ParseException e2) { + Log.e(TAG, "remoteEventsAdapter.getView: Error Parsing dataDate " + e2.getLocalizedMessage()); + dataTime = null; + } + } + return(dataTime); + } public final int ALARM_STATUS_WARNING = 1; diff --git a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java index 9b557de..f63e1b2 100644 --- a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java +++ b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection.java @@ -43,8 +43,8 @@ import java.util.Map; // This class is intended to handle all interactions with the OSD WebAPI public abstract class WebApiConnection { - private Context mContext; - private OsdUtil mUtil; + protected Context mContext; + protected OsdUtil mUtil; private String TAG = "WebApiConnection"; private String mAuthToken; diff --git a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection_osdapi.java b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection_osdapi.java index e6f8f91..57aa908 100644 --- a/app/src/main/java/uk/org/openseizuredetector/WebApiConnection_osdapi.java +++ b/app/src/main/java/uk/org/openseizuredetector/WebApiConnection_osdapi.java @@ -32,8 +32,6 @@ public class WebApiConnection_osdapi extends WebApiConnection { public boolean mServerConnectionOk = false; private String mUrlBase = "https://osdApi.ddns.net"; private String TAG = "WebApiConnection_osdapi"; - private Context mContext; - private OsdUtil mUtil; RequestQueue mQueue; public WebApiConnection_osdapi(Context context) { @@ -155,9 +153,18 @@ public class WebApiConnection_osdapi extends WebApiConnection { new Response.Listener() { @Override public void onResponse(String response) { - Log.v(TAG, "Response is: " + response); + Log.v(TAG, "createEvent.onResponse - Response is: " + response); mServerConnectionOk = true; - callback.accept(response); + // we return just the eventId to be consistent with the firebase version of WebApiConnection. + String retVal = null; + try { + JSONObject retObj = new JSONObject(response); + retVal = retObj.getString("id"); + } catch (JSONException e) { + Log.e(TAG, "createEvent.onResponse(): Error: " + e.getMessage() + "," + e.toString()); + retVal = null; + } + callback.accept(retVal); } }, new Response.ErrorListener() { @@ -165,10 +172,10 @@ public class WebApiConnection_osdapi extends WebApiConnection { public void onErrorResponse(VolleyError error) { mServerConnectionOk = false; if (error != null) { - Log.e(TAG, "Create Event Error: " + error.toString() + ", message:" + error.getMessage()); + Log.e(TAG, "createEvent Error: " + error.toString() + ", message:" + error.getMessage()); callback.accept(null); } else { - Log.e(TAG, "Create Event Error - null respones"); + Log.e(TAG, "createEvent Error - null response"); callback.accept(null); } } @@ -208,7 +215,6 @@ public class WebApiConnection_osdapi extends WebApiConnection { } public boolean getEvent(String eventId, JSONObjectCallback callback) { - //Long eventId=Long.valueOf(285); Log.v(TAG, "getEvent()"); String urlStr = mUrlBase + "/api/events/" + eventId; Log.v(TAG, "getEvent(): urlStr=" + urlStr); @@ -267,7 +273,6 @@ public class WebApiConnection_osdapi extends WebApiConnection { * @return true on success or false on failure to initiate the request. */ public boolean getEvents(JSONObjectCallback callback) { - //Long eventId=Long.valueOf(285); Log.v(TAG, "getEvents()"); String urlStr = mUrlBase + "/api/events/"; Log.v(TAG, "getEvents(): urlStr=" + urlStr); @@ -327,7 +332,7 @@ public class WebApiConnection_osdapi extends WebApiConnection { public boolean updateEvent(final JSONObject eventObj, JSONObjectCallback callback) { - Long eventId; + String eventId; Log.v(TAG, "updateEvent()"); final String authtoken = getStoredToken(); @@ -336,18 +341,17 @@ public class WebApiConnection_osdapi extends WebApiConnection { return (false); } try { - eventId = eventObj.getLong("id"); + eventId = eventObj.getString("id"); } catch (JSONException e) { Log.e(TAG, "updateEvent(): Error reading id from eventObj"); - eventId = Long.valueOf(-1); + eventId = null; } final String dataStr = eventObj.toString(); - Log.v(TAG, "createEvent - data=" + dataStr); - + Log.v(TAG, "updateEvent - data=" + dataStr); int reqMethod; String urlStr; - if (eventId != -1) { + if (eventId != null) { Log.v(TAG, "updateEvent() - found eventId " + eventId + ", Updating event record"); urlStr = mUrlBase + "/api/events/" + eventId + "/"; Log.v(TAG, "urlStr=" + urlStr);