11package com .eveningoutpost .dexdrip .models ;
22
3+ import static com .eveningoutpost .dexdrip .models .JoH .tsl ;
4+
35import android .provider .BaseColumns ;
46
57import com .activeandroid .Model ;
68import com .activeandroid .annotation .Column ;
79import com .activeandroid .annotation .Table ;
10+ import com .activeandroid .query .Delete ;
811import com .activeandroid .query .Select ;
912import com .eveningoutpost .dexdrip .GcmActivity ;
1013import com .eveningoutpost .dexdrip .Home ;
2124
2225import java .util .Date ;
2326import java .util .List ;
27+ import java .util .Objects ;
2428import java .util .UUID ;
2529
30+ import lombok .Setter ;
31+ import lombok .val ;
32+
2633/**
2734 * Created by Emma Black on 10/29/14.
2835 */
@@ -52,22 +59,25 @@ public class Sensor extends Model {
5259 @ Column (name = "sensor_location" )
5360 public String sensor_location ;
5461
55- public synchronized static Sensor create (long started_at ) {
56- Sensor sensor = new Sensor ();
57- sensor .started_at = started_at ;
58- sensor .uuid = UUID .randomUUID ().toString ();
5962
60- sensor .save ();
61- SensorSendQueue .addToQueue (sensor );
62- Log .d ("SENSOR MODEL:" , sensor .toString ());
63- return sensor ;
63+ @ Setter
64+ private volatile static long unitTestStopTime ;
65+
66+ public synchronized static Sensor create (long starting_at ) {
67+ stopSensor (true ); // stop any existing sensor session clamping to the last reading
68+ return create (starting_at , UUID .randomUUID ().toString ());
6469 }
6570
66- public synchronized static Sensor create (long started_at , String uuid ) {//KS
71+ public synchronized static Sensor create (long starting_at , String uuid ) {//KS
6772 Sensor sensor = new Sensor ();
68- sensor .started_at = started_at ;
73+ val lastSensor = lastStopped (); // get the last sensor we stopped
74+ // find the time it was stopped or 0 if there is no previous sensor
75+ long lastStoppedTime = lastSensor != null ? lastSensor .stopped_at : 0 ;
76+ sensor .started_at = Math .max (lastStoppedTime + 1 , starting_at );
77+ if (sensor .started_at > tsl ()) {
78+ UserError .Log .wtf (TAG , "Sensor create() called with future timestamp, this cannot be right. " + starting_at + " " + lastStoppedTime + " " + sensor .started_at );
79+ }
6980 sensor .uuid = uuid ;
70-
7181 sensor .save ();
7282 SensorSendQueue .addToQueue (sensor );
7383 Log .d ("SENSOR MODEL:" , sensor .toString ());
@@ -77,19 +87,36 @@ public synchronized static Sensor create(long started_at, String uuid) {//KS
7787 public static Sensor createDefaultIfMissing () {
7888 final Sensor sensor = currentSensor ();
7989 if (sensor == null ) {
80- Sensor .create (JoH . tsl ());
90+ Sensor .create (tsl ());
8191 UserError .Log .ueh (TAG , "Created new default sensor" );
8292 }
8393 return currentSensor ();
8494 }
8595
8696 public synchronized static void stopSensor () {
97+ stopSensor (false ); // by default don't clamp to last reading
98+ }
99+
100+
101+ public synchronized static void stopSensor (final boolean clampToLastReading ) {
87102 final Sensor sensor = currentSensor ();
88103 if (sensor == null ) {
89104 return ;
90105 }
91- sensor .stopped_at = JoH .tsl ();
92- UserError .Log .ueh ("SENSOR" , "Sensor stopped at " + JoH .dateTimeText (sensor .stopped_at ));
106+
107+ // stop now or use specified unit testing stop time
108+ sensor .stopped_at = (unitTestStopTime == 0 ) ? tsl () : unitTestStopTime ;
109+
110+ if (clampToLastReading ) {
111+ val lastReading = BgReading .last (true );
112+ if (lastReading != null ) {
113+ // if we have a last reading then set the stop time to that last reading so long as it
114+ // was actually from this sensor
115+ sensor .stopped_at = Math .max (sensor .started_at , lastReading .timestamp + 1 );
116+ }
117+ }
118+
119+ UserError .Log .ueh ("SENSOR" , "Sensor stopped at value: " + JoH .dateTimeText (sensor .stopped_at ));
93120 sensor .save ();
94121 if (currentSensor () != null ) {
95122 UserError .Log .wtf (TAG , "Failed to update sensor stop in database" );
@@ -122,36 +149,31 @@ public static Sensor lastStopped() {
122149
123150 public static boolean stoppedRecently () {
124151 final Sensor last = lastStopped ();
125- return last != null && last .stopped_at < JoH . tsl () && (JoH .msSince (last .stopped_at ) < (Constants .HOUR_IN_MS * 2 ));
152+ return last != null && last .stopped_at < tsl () && (JoH .msSince (last .stopped_at ) < (Constants .HOUR_IN_MS * 2 ));
126153 }
127154
128155 public static Sensor currentSensor () {
129156 Sensor sensor = new Select ()
130157 .from (Sensor .class )
131158 .where ("started_at != 0" )
132- .where ("stopped_at = 0" )
133159 .orderBy ("_ID desc" )
134160 .limit (1 )
135161 .executeSingle ();
162+
163+ if (sensor != null ) {
164+ if (sensor .stopped_at != 0 ) {
165+ // last sensor is stopped
166+ return null ;
167+ }
168+ }
136169 return sensor ;
137170 }
138171
139172 public static boolean isActive () {
140- Sensor sensor = new Select ()
141- .from (Sensor .class )
142- .where ("started_at != 0" )
143- .where ("stopped_at = 0" )
144- .orderBy ("_ID desc" )
145- .limit (1 )
146- .executeSingle ();
147- if (sensor == null ) {
148- return false ;
149- } else {
150- return true ;
151- }
173+ return currentSensor () != null ;
152174 }
153175
154- public static Sensor getByTimestamp (double started_at ) {
176+ public static Sensor getByTimestamp (long started_at ) {
155177 return new Select ()
156178 .from (Sensor .class )
157179 .where ("started_at = ?" , started_at )
@@ -259,6 +281,14 @@ public static void upsertFromMaster(Sensor jsonSensor) {
259281 }
260282 }
261283
284+ public static void deleteAll () {
285+ // will fail if bg readings not deleted first
286+ SensorSendQueue .deleteAll ();
287+ new Delete ()
288+ .from (Sensor .class )
289+ .execute ();
290+ }
291+
262292 public String toJSON () {
263293 JSONObject jsonObject = new JSONObject ();
264294 try {
@@ -273,6 +303,34 @@ public String toJSON() {
273303 return "" ;
274304 }
275305 }
306+
307+ @ Override
308+ public String toString () {
309+ return "SENSOR: " + toJSON () + " started: " + JoH .dateTimeText (started_at ) + ((stopped_at != 0 ) ? " stopped: " + JoH .dateTimeText (stopped_at ) : "" );
310+ }
311+
312+ @ Override
313+ public boolean equals (Object obj ) {
314+ if (this == obj ) { // Check for reference equality
315+ return true ;
316+ }
317+ if (obj == null || getClass () != obj .getClass ()) { // Check for null and class type
318+ return false ;
319+ }
320+ Sensor sensor = (Sensor ) obj ; // Typecast
321+
322+ return started_at == sensor .started_at
323+ // && stopped_at == sensor.stopped_at // Note: not checking stopped_at as this maybe transient
324+ && latest_battery_level == sensor .latest_battery_level
325+ && Objects .equals (uuid , sensor .uuid )
326+ && Objects .equals (sensor_location , sensor .sensor_location );
327+
328+ }
329+
330+ @ Override
331+ public int hashCode () {
332+ return Objects .hash (started_at , stopped_at , latest_battery_level , uuid , sensor_location );
333+ }
276334
277335 public static Sensor fromJSON (String json ) {
278336 if (json .length ()==0 ) {
0 commit comments