init

Dependencies:   aconno_I2C Lis2dh12 WatchdogTimer

Files at this revision

API Documentation at this revision

Comitter:
pathfindr
Date:
Sun Jan 20 21:40:53 2019 +0000
Parent:
44:061509d1b38c
Child:
46:b95fe3484d88
Commit message:
added total runtime hours and activity mode

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show annotated file Show diff for this revision Revisions of this file
--- a/main.cpp	Sun Jan 20 12:50:31 2019 +0000
+++ b/main.cpp	Sun Jan 20 21:40:53 2019 +0000
@@ -3,7 +3,8 @@
 //------------------------------------------------------------------------------
 //FUNCTION PROTOTYPES - NEED TO ADD ALL OF THE MISSING ONES
 //------------------------------------------------------------------------------ 
-//should really add these
+//should really add these - will just add as and when needed for now
+void event_activity_tx(uint8_t activity_mode);
 
 //------------------------------------------------------------------------------
 // GLOBALS
@@ -29,6 +30,7 @@
 uint32_t         RET_setting_location_tx_failsafe_hrs;
 uint16_t         RET_setting_location_timeout;
 uint32_t         RET_setting_activity_tx_interval_hrs;
+uint8_t          RET_setting_activity_mode;
 uint32_t         RET_setting_environmental_tx_interval_mins;
 uint16_t         RET_setting_motion_g;
 time_t           RET_setting_motion_start_seconds;
@@ -53,17 +55,19 @@
 bool             RET_setupInProgress;
 bool             RET_force2G;
 bool             RET_watchdogfired;
+bool             RET_receivedNewSettings;
 //MOTION STATE
 bool             RET_motionTriggeredinFrame;
-bool             RET_motionTriggeredInTXInterval;
+bool             RET_motionTriggeredInLocTXInterval;
 time_t           RET_motionStartTime;
 time_t           RET_motionStopTime;
 bool             RET_motionPendingOnState;
 bool             RET_motionPendingOffState;
 bool             RET_motionState;
 float            RET_motionTotalActivityHours;
+float            RET_motionTotalActivityHoursSincePost;
 time_t           RET_motionFrameStart;
-char             RET_activityData[140];
+char             RET_activityData[ACTIVITY_BUFFERSIZE];
 //IMPACT
 bool             RET_impactTriggered;
 //EVENTS LOGGING
@@ -108,7 +112,6 @@
     RET_state_prev = RET_state;
     RET_state = state;
 }
-
 void dumpSettings() {    
     if(DEBUG_ON){
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_RTCunixtime:%u", RET_RTCunixtime);debug_exe();
@@ -121,6 +124,7 @@
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_tx_failsafe_hrs:%d", RET_setting_location_tx_failsafe_hrs);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_location_timeout:%d", RET_setting_location_timeout);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_activity_tx_interval_hrs:%d", RET_setting_activity_tx_interval_hrs);debug_exe();
+        debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_activity_mode:%d", RET_setting_activity_mode);debug_exe();        
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_environmental_tx_interval_mins:%d", RET_setting_environmental_tx_interval_mins);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_motion_g:%d", RET_setting_motion_g);debug_exe();
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_motion_start_seconds:%d", RET_setting_motion_start_seconds);debug_exe();
@@ -132,6 +136,23 @@
         debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "RET_setting_beacon_scan:%d", RET_setting_beacon_scan);debug_exe();
     }
 }
+void recordFirmwareAsValid() {
+    read_app_data_from_flash(&app_data);
+    bool write_app_data_to_flash_execute = false;
+    if(get_flag(&app_data, app_execution_flag) == true) {
+        clr_flag(&app_data, app_execution_flag);
+        clr_flag(&app_data, first_run_flag);
+        write_app_data_to_flash_execute = true;
+    }
+    if(app_data.current_firmware_version != FW_VERSION) {
+        app_data.current_firmware_version = FW_VERSION;
+        app_data.target_firmware_version = FW_VERSION;
+        write_app_data_to_flash_execute = true;
+    }
+    if (write_app_data_to_flash_execute) {
+        write_app_data_to_flash(&app_data);
+    }   
+}
 float getBatteryV() {
     NRF52_SAADC batteryIn;
     batteryIn.addChannel(9); // vdd for battery
@@ -167,7 +188,9 @@
     return temperature;  
 }
 void addToExceptionString(char* value) {
-    snprintf(GLOBAL_exceptionString+strlen(GLOBAL_exceptionString),sizeof(GLOBAL_exceptionString),"%s.",value);
+    if(strstr(GLOBAL_exceptionString, value) == false){
+        snprintf(GLOBAL_exceptionString+strlen(GLOBAL_exceptionString),sizeof(GLOBAL_exceptionString),"%s.",value);
+    }
 }
 //------------------------------------------------------------------------------
 // USER BUTTON HANDLING
@@ -289,6 +312,7 @@
     RET_force2G = DEFAULT_FORCE2G;
     RET_watchdogfired = false;
     RET_setupInProgress = false;
+    RET_receivedNewSettings = false;
     //SETTINGS
     RET_setting_firmware = 0;
     RET_setting_minimumupdate_hrs = 0;
@@ -298,6 +322,7 @@
     RET_setting_location_tx_failsafe_hrs = DEFAULT_LOCATION_TX_FAILSAFE_HRS;
     RET_setting_location_timeout = DEFAULT_LOCATION_TIMEOUT;
     RET_setting_activity_tx_interval_hrs = 0;
+    RET_setting_activity_mode = 1;
     RET_setting_environmental_tx_interval_mins = 0;
     RET_setting_motion_g = DEFAULT_MOTION_G;
     RET_setting_motion_start_seconds = DEFAULT_MOTION_START_SECONDS;
@@ -311,14 +336,15 @@
     RET_buttonPressTime = 0;
     RET_buttonHoldTime = 0;
     //MOTION STATE
-    RET_motionTriggeredinFrame = 0;
-    RET_motionTriggeredInTXInterval = 0;
+    RET_motionTriggeredinFrame = false;
+    RET_motionTriggeredInLocTXInterval = false;
     RET_motionStartTime = 0;
     RET_motionStopTime = 0;
     RET_motionPendingOnState = 0;
     RET_motionPendingOffState = 0;
     RET_motionState = 0;
     RET_motionTotalActivityHours = 0.0;
+    RET_motionTotalActivityHoursSincePost = 0.0;
     RET_motionFrameStart = 0;
     memset(RET_activityData,0x00,sizeof(RET_activityData));
     //IMPACT
@@ -402,30 +428,35 @@
     //calculate motion state
     if (RET_motionPendingOnState) {
         //check if above threshold
-        time_t inMotionForSeconds = (RET_RTCunixtime - RET_motionStartTime) + (DEFAULT_SLEEP_FRAME / 1000); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
-        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOT:%d s",inMotionForSeconds);debug_exe();}
+        time_t inMotionForSeconds = ((RET_RTCunixtime - RET_motionStartTime) + (DEFAULT_SLEEP_FRAME / 1000)); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOT:%u s",inMotionForSeconds);debug_exe();}
         if (inMotionForSeconds >= RET_setting_motion_start_seconds && RET_motionState == false) {
             RET_motionState = true;
-            RET_motionTriggeredInTXInterval = true;
+            RET_motionTriggeredInLocTXInterval = true;
             //if (GLOBAL_debugLED) LED1blink(1,50);
-            if (RET_setting_location_tx_failsafe_hrs > 0) {
-                time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
-                sprintf(RET_activityData+strlen(RET_activityData),"1.%u!",epochOffsetMins);
+            if (RET_setting_activity_mode == 2) {
+                if (RET_setting_location_tx_failsafe_hrs > 0) {
+                    time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
+                    sprintf(RET_activityData+strlen(RET_activityData),"1.%u!",epochOffsetMins);
+                }
             }
         }
     }
     if (RET_motionPendingOffState) {
-        time_t noMotionForSeconds = (RET_RTCunixtime - RET_motionStopTime) + (DEFAULT_SLEEP_FRAME / 1000); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
-        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOTLESS:%d s",noMotionForSeconds);debug_exe();}
+        time_t noMotionForSeconds = ((RET_RTCunixtime - RET_motionStopTime) + (DEFAULT_SLEEP_FRAME / 1000)); //Plus DEFAULT_SLEEP_FRAME as it should include frame time
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "MOTLESS:%u s",noMotionForSeconds);debug_exe();}
         if (noMotionForSeconds >= RET_setting_motion_stop_seconds && RET_motionState == true) {
             //if (GLOBAL_debugLED) LED1blink(2,50);
             RET_motionPendingOffState = false;
             RET_motionState = false;
             GLOBAL_motionStopFlagTriggered = true;
             if (RET_setting_location_tx_failsafe_hrs > 0) {
-                RET_motionTotalActivityHours += ((float(RET_motionStopTime)-float(RET_motionStartTime)) / 3600.0f);
-                time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
-                sprintf(RET_activityData+strlen(RET_activityData),"0.%u!",epochOffsetMins);
+                RET_motionTotalActivityHoursSincePost += ((float(RET_motionStopTime)-float(RET_motionStartTime)) / 3600.0f);
+                RET_motionTotalActivityHours += RET_motionTotalActivityHoursSincePost;
+                if (RET_setting_activity_mode == 2) {
+                    time_t epochOffsetMins = ((RET_RTCunixtime - RET_motionFrameStart) / 60);
+                    sprintf(RET_activityData+strlen(RET_activityData),"0.%u!",epochOffsetMins);
+                }
             }
         }
     }
@@ -438,11 +469,12 @@
     int matchCount = 0;
     int critical_fail_count = 0;
     int TEMP_a = -1; time_t TEMP_b = 0; int TEMP_c = -1; int TEMP_d = -1; int TEMP_e = -1; int TEMP_f = -1; int TEMP_g = -1; int TEMP_h = -1; int TEMP_i = -1; int TEMP_j = -1; 
-    int TEMP_k = -1; int TEMP_l = -1; int TEMP_m = -1; int TEMP_n = -1; int TEMP_o = -1; int TEMP_p = -1; int TEMP_q = -1; int TEMP_r = -1; int TEMP_s = -1;
-    if ( (matchCount = sscanf(settingsBuffer,"a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d",
-    &TEMP_a,&TEMP_b,&TEMP_c,&TEMP_d,&TEMP_e,&TEMP_f,&TEMP_g,&TEMP_h,&TEMP_i,&TEMP_j,&TEMP_k,&TEMP_l,&TEMP_m,&TEMP_n,&TEMP_o,&TEMP_p,&TEMP_q,&TEMP_r,&TEMP_s) ) > 0 ) {
-        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "FROMSERVER: a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d\n",
-        TEMP_a,TEMP_b,TEMP_c,TEMP_d,TEMP_e,TEMP_f,TEMP_g,TEMP_h,TEMP_i,TEMP_j,TEMP_k,TEMP_l,TEMP_m,TEMP_n,TEMP_o,TEMP_p,TEMP_q,TEMP_r,TEMP_s);debug_exe();}
+    int TEMP_k = -1; int TEMP_l = -1; int TEMP_m = -1; int TEMP_n = -1; int TEMP_o = -1; int TEMP_p = -1; int TEMP_q = -1; int TEMP_r = -1; int TEMP_s = -1; int TEMP_t = -1;
+    int varTotal = 19; //change this if var number changes!!!!!!!!
+    if ( (matchCount = sscanf(settingsBuffer,"a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d,t:%d",
+    &TEMP_a,&TEMP_b,&TEMP_c,&TEMP_d,&TEMP_e,&TEMP_f,&TEMP_g,&TEMP_h,&TEMP_i,&TEMP_j,&TEMP_k,&TEMP_l,&TEMP_m,&TEMP_n,&TEMP_o,&TEMP_p,&TEMP_q,&TEMP_r,&TEMP_s,&TEMP_t) ) > 0 ) {
+        if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "FROMSERVER: a:%d,b:%u,c:%d,d:%d,e:%d,f:%d,g:%d,h:%d,i:%d,j:%d,k:%d,l:%d,m:%d,n:%d,o:%d,p:%d,q:%d,r:%d,s:%d,t:%d\n",
+        TEMP_a,TEMP_b,TEMP_c,TEMP_d,TEMP_e,TEMP_f,TEMP_g,TEMP_h,TEMP_i,TEMP_j,TEMP_k,TEMP_l,TEMP_m,TEMP_n,TEMP_o,TEMP_p,TEMP_q,TEMP_r,TEMP_s,TEMP_t);debug_exe();}
         
         if(TEMP_a != -1) { RET_setting_minimumupdate_hrs = TEMP_a;                      }
         if(TEMP_b != 0)  { RET_RTCunixtime = TEMP_b;                                    } else { critical_fail_count++; }
@@ -469,8 +501,10 @@
             if(RET_setting_connection_timeout < 60 || RET_setting_connection_timeout > 240) { RET_setting_connection_timeout = DEFAULT_CONNECTION_TIMEOUT; }
         if(TEMP_r != -1) { RET_setting_beacon_interval_seconds = TEMP_r;                }
         if(TEMP_s != -1) { RET_setting_beacon_scan = TEMP_s;                            }
-        
+        if(TEMP_t != -1) { RET_setting_activity_mode = TEMP_t;                          }
+
         if (critical_fail_count == 0) { 
+            RET_receivedNewSettings = true;
             if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "SETTINGS OK");debug_exe();}
             dumpSettings();
             RET_haveSettings = true;
@@ -479,6 +513,9 @@
             //check for firmware update
             if (RET_setting_firmware > 0 && RET_setting_firmware != FW_VERSION) {
                 read_app_data_from_flash(&app_data);
+                clr_flag(&app_data, app_execution_flag);
+                clr_flag(&app_data, first_run_flag);
+                app_data.current_firmware_version = FW_VERSION;
                 app_data.target_firmware_version = RET_setting_firmware;
                 write_app_data_to_flash(&app_data);
                 if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "OTA\n");debug_exe();}
@@ -559,23 +596,25 @@
     float temperature = getTemperature();
     float voltage = getBatteryV();
     bool selftestresult = selfTest();
-    if (selftestresult == false) { LED1errorCode(4,20); } //ERROR 4
+    if (selftestresult == false) { LED1errorCode(4,10); } //ERROR 4
+    int connectionStartTime = RET_RTCunixtime;
     if (modem.on(RET_force2G)) {
         char locString[70];
+        int gpsStartTime = RET_RTCunixtime;
         memcpy(locString, modem.getLocation(1, RET_setting_location_timeout), 70);
+        int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
         if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-            int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
+            int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
+            int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
             if (manualrun) addToExceptionString("MAN");
             char bytestosend[160];
-            snprintf(bytestosend,sizeof(bytestosend),"(%s,a:setup,f:%d,v:%.2f,t:%.1f,e:%d,z:SETUP-%s,k:%s,m:%s,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,voltage,temperature,timetaken,GLOBAL_exceptionString,SKU,HW_MAJORREVISION,locString);
+            snprintf(bytestosend,sizeof(bytestosend),"(%s,a:setup,f:%d,v:%.2f,t:%.1f,e:%d,y:%d,x:%d,z:SETUP-%s,k:%s,m:%s,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,voltage,temperature,timetaken_total,timetaken_connection,timetaken_gps,GLOBAL_exceptionString,SKU,HW_MAJORREVISION,locString);
             char result[200];
             snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, true, 2, GLOBAL_defaultApi));
             if (strcmp(result, "err") != 0) {
                 if (saveSettings(result) == false) {
                     //something went critically wrong getting settings 
                     pass = false;
-                    modem.off(true);
-                    if(GLOBAL_debugLED) LED1errorCode(5,10); //ERROR 5
                     sendErrorLog("ERR:SU-IR");
                 }                      
             } else {
@@ -594,10 +633,12 @@
         if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 2
         pass = false;
     }
+    //SEND ANY ACTIVITY DATA
+    event_activity_tx(RET_setting_activity_mode);
     modem.off(true);
+    
     //LOG RUN TIME - THIS MUST GO AT END AFTER WE HAVE GOT SERVER TIMESTAMP
     RET_SetupRunAt = RET_RTCunixtime;
-    //SET ALL EVENT TIMES
     setEventTimes();
     RET_setupInProgress = false; //this turns off the flashing led
     //RESULT
@@ -607,16 +648,20 @@
 void event_turnonofflog_tx(bool turnon) {
     float temperature = getTemperature();
     float voltage = getBatteryV();
+    int connectionStartTime = RET_RTCunixtime;
     if (modem.on(RET_force2G)) {
         char locString[70];
+        int gpsStartTime = RET_RTCunixtime;
         memcpy(locString, modem.getLocation(1, RET_setting_location_timeout), 70);
+        int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
         if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-            int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.;
+            int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime);
+            int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
             char bytestosend[160];
             if (turnon) {
-                snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNON,e:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,timetaken,locString);
+                snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNON,e:%d,y:%d,x:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
             } else {
-                snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNOFF,e:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,timetaken,locString);
+                snprintf(bytestosend,sizeof(bytestosend),"(%s,a:log,f:%d,t:%.1f,v:%.2f,z:TURNOFF,e:%d,y:%d,x:%d,c:1,s:1%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,timetaken_total,timetaken_connection,timetaken_gps,locString);
             }
             char result[180];
             snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytestosend, false, 2, GLOBAL_defaultApi));
@@ -627,25 +672,29 @@
         modem.off(true);
     }
     modem.off(true);
-    //RESETS
-    RET_motionTriggeredInTXInterval = 0;
 }
 
 void event_location_tx() {
     float temperature = getTemperature();
     float voltage = getBatteryV();
     int selfTestResult = selfTest();
+    int connectionStartTime = RET_RTCunixtime;
+    if (RET_receivedNewSettings) {RET_receivedNewSettings = false; addToExceptionString("SR"); }
     if (modem.on(RET_force2G)) {
         char locString[70];
+        int gpsStartTime = RET_RTCunixtime;
         memcpy(locString, modem.getLocation(RET_setting_location_accuracy, RET_setting_location_timeout), 70);
+        int timetaken_gps = (RET_RTCunixtime - gpsStartTime);
         //SEND DATA
         if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-            int timetaken = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time 
+            int timetaken_total = (RET_RTCunixtime - GLOBAL_wakeTime) + 10; //add 10 for ussd response time.
+            int timetaken_connection = (RET_RTCunixtime - connectionStartTime);
             //Check if we should wait for settings back
             bool getSettings = true;
-            if (  ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs  ) { getSettings = false; timetaken -= 10;} //remove the extra 10 seconds from times
+            //work out if we need to get settings back
+            if (  ((RET_RTCunixtime - RET_SettingsGotAt)/3600) < RET_setting_minimumupdate_hrs  ) { getSettings = false; timetaken_total -= 10;} //remove the extra 10 seconds from times
             char bytesToSend[160];
-            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.1f,v:%.2f,z:LOC-%s,e:%d,c:1,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,GLOBAL_exceptionString,timetaken,getSettings,locString);
+            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:loc,f:%d,t:%.1f,v:%.2f,z:LOC-%s,e:%d,y:%d,x:%d,c:1,s:%d%s)\0",GLOBAL_defaultApi,FW_VERSION,temperature,voltage,GLOBAL_exceptionString,timetaken_total,timetaken_connection,timetaken_gps,getSettings,locString);
             char result[180];
             snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getSettings, 2, GLOBAL_defaultApi));
             if (result != "err") {
@@ -665,37 +714,44 @@
     }
     modem.off(true);
     //RESETS
-    RET_motionTriggeredInTXInterval = 0;
+    RET_motionTriggeredInLocTXInterval = false;
     setEventTime_Location();
 }
 
-void event_activity_tx() {
-    float temperature = getTemperature();
-    float voltage = getBatteryV();
-    if (modem.on(RET_force2G)) {
-        //SEND DATA
-        if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
-            char bytesToSend[160];
-            snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHours);
-            char result[180];
-            bool getResponse = false;
-            snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, 2, GLOBAL_defaultApi));
-            if (result != "err") {
-                //RESET ACTIVITY FRAME
-                memset(RET_activityData,0,sizeof(RET_activityData));
-                if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; }
+void event_activity_tx(uint8_t activity_mode) {
+    //SEND ACTIVITY DATA
+    //check we have something to send...
+    if (RET_motionTotalActivityHoursSincePost > 0.0 && activity_mode > 0) {
+        float temperature = getTemperature();
+        float voltage = getBatteryV();
+        if (modem.on(RET_force2G)) {
+            //SEND DATA
+            if (modem.registerOnNetwork(DEFAULT_CONNECTION_ATTEMPTS,(RET_setting_connection_timeout*1000))) {
+                char bytesToSend[160];
+                if (activity_mode == 1) {
+                    snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,t:%u,r:%.2f,h:%.2f,c:1)\0",GLOBAL_defaultApi,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours);
+                } else if (activity_mode == 2) {
+                    snprintf(bytesToSend,sizeof(bytesToSend),"(%s,a:act,e:%s,t:%u,r:%.2f,c:1)\0",GLOBAL_defaultApi,RET_activityData,RET_motionFrameStart,RET_motionTotalActivityHoursSincePost);
+                }
+                char result[180];
+                bool getResponse = false;
+                snprintf(result,sizeof(result),"%s",modem.USSDmessage(bytesToSend, getResponse, 2, GLOBAL_defaultApi));
+                if (result != "err") {
+                    //RESET ACTIVITY FRAME
+                    memset(RET_activityData,0,sizeof(RET_activityData));
+                    if (RET_haveSettings) { RET_motionFrameStart = RET_RTCunixtime; }
+                }
+            } else {
+                modem.off(true);
+                if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3
             }
         } else {
             modem.off(true);
-            if(GLOBAL_debugLED) LED1errorCode(3,10); //ERROR 3
+            if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 3
         }
-    } else {
         modem.off(true);
-        if(GLOBAL_debugLED) LED1errorCode(2,10); //ERROR 3
     }
-    modem.off(true);
     //RESETS
-    RET_motionTriggeredInTXInterval = 0;
     setEventTime_Activity();
 }
 
@@ -733,7 +789,7 @@
                     break;
                 case 2: //INTERVAL POST WITH MOTION CHECK
                     if(RET_RTCunixtime >= RET_eventTime_location_tx && RET_eventTime_location_tx > 0) { 
-                        if (RET_motionTriggeredInTXInterval) {
+                        if (RET_motionTriggeredInLocTXInterval == true) {
                             run_location_tx = true;
                         } else {
                              if(DEBUG_ON){debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "Skip TX no mot\n");debug_exe();}
@@ -750,11 +806,17 @@
             
             //ACTIVITY EVENT
             bool run_activity_tx = false;
-            if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0 && strlen(RET_activityData) > 1) { 
-                run_activity_tx = true;
+            if(RET_RTCunixtime >= RET_eventTime_activity_tx && RET_eventTime_activity_tx > 0) {
+                if (RET_setting_activity_mode == 1 && RET_motionTotalActivityHoursSincePost > 0.0) {
+                    run_activity_tx = true;
+                }
+                if (RET_setting_activity_mode == 2 && strlen(RET_activityData) > 1) {
+                    run_activity_tx = true;
+                }
             }
-            if (strlen(RET_activityData) > 8) { run_activity_tx = true; } //was 130
-            if (run_activity_tx) { event_activity_tx();}
+            //If in sendevent mode, check if buffer is close to full, if so send
+            if (RET_setting_activity_mode == 2 && strlen(RET_activityData) > (ACTIVITY_BUFFERSIZE-20)) { run_activity_tx = true; }
+            if (run_activity_tx) { event_activity_tx(RET_setting_activity_mode); }
             break;
         }
         case STATE_DORMANT :
@@ -910,8 +972,8 @@
         //MAIN LOGIC
         if(DEBUG_ON){
             if (RET_state != 99) {
-                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d,S:%d, SET:%d, MF:%d, MS: %d, %u, L:%u, LFS:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_RTCunixtime,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
-                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ACT:%s\n",RET_activityData);debug_exe();
+                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, SET:%d, MF:%d, MS:%d, MTX:%d, %u, L:%u, LFS:%u, A:%u", FW_VERSION, RET_state, RET_haveSettings, RET_motionTriggeredinFrame, RET_motionState, RET_motionTriggeredInLocTXInterval, RET_RTCunixtime,RET_eventTime_location_tx,RET_eventTime_location_failsafe_tx,RET_eventTime_activity_tx);debug_exe();
+                debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "ACT M:%d, HsP:%.2f, Ht:%.2f D:%s\n",RET_setting_activity_mode,RET_motionTotalActivityHoursSincePost,RET_motionTotalActivityHours,RET_activityData);debug_exe();
             } else {
                 debug_prep();snprintf(GLOBAL_debug_buffer, sizeof(GLOBAL_debug_buffer), "F:%d, S:%d, WAKE@:%u\n", FW_VERSION, RET_state, RET_eventTime_wakeFromDormant);debug_exe();
             }
@@ -930,31 +992,17 @@
                 
         //LOG FIRST RUN - BOOTLOADER COMMS
         if (RET_coldBoot) {
-            read_app_data_from_flash(&app_data);
-            bool write_app_data_to_flash_execute = false;
-            if(get_flag(&app_data, app_execution_flag) == true) {
-                clr_flag(&app_data, app_execution_flag);
-                clr_flag(&app_data, first_run_flag);
-                write_app_data_to_flash_execute = true;
-            }
-            if(app_data.current_firmware_version != FW_VERSION) {
-                app_data.current_firmware_version = FW_VERSION;
-                app_data.target_firmware_version = FW_VERSION;
-                write_app_data_to_flash_execute = true;
-            }
-            if (write_app_data_to_flash_execute) {
-                write_app_data_to_flash(&app_data);
-            }
+            recordFirmwareAsValid();
             RET_coldBoot = 0;
         }
         
         //PRE-SLEEP ACTIONS
+        LED1off();
+        modem.off(false);
         RET_motionTriggeredinFrame = false;
-        LED1off();
         if (GLOBAL_needToConfigureLis3dh) { lis3dh_configureForSleep(RET_setting_motion_g,RET_setting_impact_g); }
-        modem.off(false);
+        nrf_configureGPIOForSleep();
         NRFuart_uninit();
-        nrf_configureGPIOForSleep();
         watchdogKick();
         
         //SLEEP
--- a/main.h	Sun Jan 20 12:50:31 2019 +0000
+++ b/main.h	Sun Jan 20 21:40:53 2019 +0000
@@ -16,7 +16,7 @@
 //------------------------------------------------------------------------------
 //DEFINES
 //------------------------------------------------------------------------------ 
-#define FW_VERSION          4
+#define FW_VERSION          8
 #define SKU                 "GPSP"
 #define HW_MAJORREVISION    "001"
 
@@ -46,6 +46,9 @@
 #define SEVENDAYSINSECONDS                  604800
 #define TENDAYSINSECONDS                    864000
 
+//DEFINES
+#define ACTIVITY_BUFFERSIZE                 100
+
 //------------------------------------------------------------------------------
 //mbed Libraries
 //------------------------------------------------------------------------------