salesforce HeartRate monitor sample application. This application sends periodic heart rate values into salesforce.com via the mbed SalesforceInterface API.

Dependencies:   BufferedSerial C12832 EthernetInterface GroveEarbudSensor Logger SalesforceInterface mbed-rtos mbed

Fork of df-2014-salesforce-hrm-k64f by Doug Anson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* Copyright C2014 ARM, MIT License
00002  *
00003  * Author: Doug Anson (doug.anson@arm.com)
00004  *
00005  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00006  * and associated documentation files the "Software", to deal in the Software without restriction,
00007  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00008  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in all copies or
00012  * substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00015  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00016  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00017  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00018  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00019  */
00020 
00021  #include "Definitions.h"       // definitions including platform specifics...
00022  #include "Logger.h"
00023  
00024  // include salesforce.com credentials
00025  #include "sf_creds.h"
00026  
00027  // our Serial port
00028  #include "BufferedSerial.h"
00029  BufferedSerial pc(USBTX, USBRX);
00030  #define LOG_CONSOLE(...) { pc.printf(__VA_ARGS__); }
00031  
00032  // mbed AppBoard Shield LCD
00033  C12832 lcd(D11, D13, D12, D7, D10);
00034  
00035  // Earbud support
00036  #include "GroveEarbudSensor.h"
00037  InterruptIn sensor(D2);
00038  GroveEarbudSensor earbud(&sensor,&pc);
00039      
00040  // Ethernet
00041  #include "EthernetInterface.h"
00042  EthernetInterface ethernet;
00043  
00044  // HTTP 
00045  #include "HTTPClient.h"
00046  HTTPClient http;
00047  
00048  // Salesforce.com Interface
00049  #include "SalesforceInterface.h"
00050  
00051  // Sensor Lat/Long - Moscone West: 37.783588, -122.403392
00052  #define SENSOR_LATITUDE     "37.783588"
00053  #define SENSOR_LONGITUDE    "-122.403392"
00054  
00055  // Salesforce.com Configuration/Tunables
00056  char *hrm_object_name          = "HeartRate__c";            // custom object 
00057  char *hrm_bpm_field_name       = "bpm__c";                  // heartrate field
00058  char *hrm_user_field_name      = "Name";                    // heartrate user
00059  char *hrm_counter_field_name   = "count__c";                // heartrate counter
00060  char *hrm_latitude             = "latitude__c";             // sensor latitude
00061  char *hrm_longitude            = "longitude__c";            // sensor longitude
00062  char *hrm_user                 = "Doug Anson";              // whos heartrate is this?
00063  
00064  // main loop toggle
00065  bool do_loop                   = true;
00066  
00067  // # retries before we give up and exit
00068  int num_retries                = MAX_TRIES;
00069   
00070  // heartrate values and iteration counter
00071  volatile int oldheartrate = HEARTRATE_OFF;
00072  volatile int iteration_counter = 1;
00073  
00074  // Salesforce.com record ID 
00075  DEFINE_SML_BUFFER(bpm_record_id);                           
00076  
00077  // Create the heart rate record in Salesforce.com
00078  void create_heartrate_record(Logger *logger,SalesforceInterface *sf) {
00079      // create a new record
00080      MbedJSONValue bpm_record;
00081      int heartrate = (int)earbud.getHeartRate();
00082      bpm_record[hrm_bpm_field_name]     = heartrate;
00083      bpm_record[hrm_user_field_name]    = hrm_user;
00084      bpm_record[hrm_counter_field_name] = (int)iteration_counter;
00085      bpm_record[hrm_latitude]           = SENSOR_LATITUDE;
00086      bpm_record[hrm_longitude]          = SENSOR_LONGITUDE;
00087      
00088      logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...",APP_VERSION,iteration_counter,heartrate);
00089      logger->logConsole("Initializing BPM record: %s",bpm_record.serialize().c_str());
00090      
00091      // create the BPM record in salesforce.com
00092      MbedJSONValue response = sf->createRecord(hrm_object_name,bpm_record);
00093      
00094      // display the result
00095      char *result = (char *)response.serialize().c_str();
00096      if (result != NULL && strlen(result) > 0 && strcmp(result,"null") != 0) {
00097         // save off the token if we succeeded
00098         logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...SUCCESS",APP_VERSION,iteration_counter,heartrate);
00099         logger->logConsole("Create: result: %s http_code = %d",result,sf->httpResponseCode());
00100         RESET_SML_BUFFER(bpm_record_id);
00101         strcpy(bpm_record_id,(char *)response["id"].get<std::string>().c_str());
00102         logger->turnLEDGreen();
00103         if (heartrate > 0) oldheartrate = heartrate;
00104         ++iteration_counter;
00105      }
00106      else {
00107         // failure
00108         logger->log("ARM Salesforce HRM v%s\r\nCreate: new bpm record(%d): %d\r\nSending...FAILED",APP_VERSION,iteration_counter,heartrate);
00109         logger->logConsole("Create: FAILED http_code=%d",sf->httpResponseCode());
00110         logger->turnLEDRed();
00111         do_loop = false;
00112      }
00113  }
00114  
00115  // Update the heart rate record in Salesforce.com
00116  void update_heartrate_record(Logger *logger,SalesforceInterface *sf) {
00117      logger->turnLEDOrange();
00118      
00119      // get our latest heartrate
00120      int heartrate = (int)earbud.getHeartRate();
00121      
00122      // only update SF if we have a valid change
00123      if (heartrate > 0 && heartrate != oldheartrate) { 
00124          // update am existing record - assume "name" is the proper key for the record you wish to update...
00125          MbedJSONValue bpm_record;
00126          bpm_record[hrm_bpm_field_name]     = heartrate;
00127          bpm_record[hrm_user_field_name]    = hrm_user;
00128          bpm_record[hrm_counter_field_name] = (int)iteration_counter;
00129          bpm_record[hrm_latitude]           = SENSOR_LATITUDE;
00130          bpm_record[hrm_longitude]          = SENSOR_LONGITUDE;
00131     
00132          // DEBUG
00133          logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...",APP_VERSION,iteration_counter,heartrate);
00134          logger->logConsole("Update: updated record: %s",bpm_record.serialize().c_str());
00135          
00136          // update the BPM record in salesforce.com
00137          bool updated = sf->updateRecord(hrm_object_name,bpm_record_id,bpm_record);
00138          
00139          // display the result
00140          if (updated) {
00141             // SUCCESS
00142             logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...SUCCESS",APP_VERSION,iteration_counter,heartrate);
00143             logger->logConsole("Update: successful! http_code=%d",sf->httpResponseCode());
00144             logger->turnLEDGreen();
00145             if (heartrate > 0) { oldheartrate = heartrate; ++iteration_counter; }
00146          }
00147          else {
00148             if (num_retries > 0) {
00149                 // retry state
00150                 logger->turnLEDPurple();
00151                 
00152                 // OAUTH token may have expired - reset and retry
00153                 logger->logConsole("Retrying update (%d of %d)...",(MAX_TRIES - num_retries)+1, MAX_TRIES);
00154                 if (num_retries == MAX_TRIES) --iteration_counter;        // one time only in retries...
00155                 --num_retries;
00156                 sf->resetSalesforceToken();
00157                 update_heartrate_record(logger,sf);
00158             }
00159             else {
00160                 // failure
00161                 logger->log("ARM Salesforce HRM v%s\r\nUpdate HR(%d): %d bpm\r\nSending...FAILED",APP_VERSION,iteration_counter,heartrate);
00162                 logger->logConsole("Update: FAILED http_code=%d",sf->httpResponseCode());
00163                 do_loop = false;
00164                 
00165                 // give-up state
00166                 logger->turnLEDRed();
00167             }
00168          }
00169      }
00170      else {
00171          logger->logConsole("Heartrate unchanged...");
00172          logger->turnLEDGreen();
00173      }
00174  }
00175  
00176  // Report heart rate to Salesforce.com
00177  void report_heartrate(Logger *logger,SalesforceInterface *sf) {
00178      if (iteration_counter == 1) create_heartrate_record(logger,sf);
00179      else update_heartrate_record(logger,sf);
00180  }
00181    
00182  // Main Task...
00183  void mainTask(void const *v) {
00184         
00185     // create our object instances 
00186     Logger logger(&pc,&lcd);    
00187     SalesforceInterface *sf = NULL;
00188     
00189     // announce
00190     logger.log("\r\n\r\nARM Salesforce HRM v%s",APP_VERSION);
00191     logger.turnLEDBlue();
00192     wait(1);
00193     
00194     // initialize Ethernet
00195     logger.log("Initializing Ethernet...");
00196     ethernet.init();
00197     
00198     // get a DHCP address and bring the network interface up
00199     logger.log("Getting IP Address...");
00200     logger.turnLEDYellow();
00201     if (ethernet.connect() == 0) {
00202         // log our IP address (DHCP)
00203         logger.log("IP Address: %s",ethernet.getIPAddress());
00204         
00205         // allocate the Salesforce.com interface
00206         logger.logConsole("Allocating the Saleforce.com interface...");
00207         sf = new SalesforceInterface(&http,&logger);
00208         
00209         // set our Salesforce.com credentials
00210         logger.logConsole("Setting credentials in the Salesforce.com interface...");
00211         sf->setCredentials(username,password,client_id,client_secret);
00212                 
00213         // enter main loop
00214         logger.logConsole("Beginning main event loop...");
00215         while(do_loop) {
00216             report_heartrate(&logger,sf);
00217             Thread::wait(WAIT_TIME_MS);
00218         }
00219         
00220         // if we fell out of the loop exit...
00221         logger.log("Application Exiting...");
00222         logger.turnLEDRed();
00223         exit(1);
00224      }
00225      else {
00226          logger.log("No Network... Exiting...");
00227          logger.turnLEDRed();
00228          exit(1);
00229      }     
00230   }
00231   
00232   // main entry
00233   int main() {
00234      Thread workerTask(mainTask, NULL, osPriorityNormal, STACK_SIZE);
00235      while (true) {
00236         Thread::wait(10*WAIT_TIME_MS);
00237      }
00238   }