Program to read Moisture and Alcohol sensor and uploads the data to Aeris Aercloud Platform.

Dependencies:   mbed

Revision:
0:dc0d8730c20e
Child:
1:78c10a2e1029
diff -r 000000000000 -r dc0d8730c20e main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jun 10 04:09:01 2015 +0000
@@ -0,0 +1,469 @@
+/*
+     Dragon Fly Sample Program for MultiTech Connected Cooler
+*/
+
+// AerCloud sample code for Dragon Fly Sample Program for MultiTech Connected Cooler - created for following hardware:
+//   ST Nucleo F411RE   http://developer.mbed.org/platforms/ST-Nucleo-F411RE/
+//   ST Sensor Board  http://developer.mbed.org/teams/ST-Americas-mbed-Team/wiki/Getting-Started-with-Nucleo-Sensors
+//   MultiTech Socket Modem Shield: http://developer.mbed.org/components/Multi-Tech-SocketModem-Arduino-Shield-MT/
+//   MultiTech http://developer.mbed.org/teams/Multi-Hackers/code/MTSAS_Cellular_HTTP_Example/
+//   MultiTech MTSMC-EV3 CDMA Socket Modem http://www.multitech.com/models/92503350LF#gsc.tab=0
+//  Details on AerCloud: http://www.aeris.com/technology/aercloud/
+//  AerCloud Developer Forum: https://developer.aeris.com/
+//
+// Sample writes moistureValue & alcoholValue to an AerCloud container
+//
+// Dependencies:
+//     mbed HTTP Client Libary
+//     DragonFly Support Library
+//     mtsas Modem Library
+//     mbed Library
+//
+// To get the sample running, you'll need to fill in the following parameters below
+//   Your cellular provider's APN: APN
+//   AerCloud API Key: AC_APIKEY
+//   AerCloud Account ID: acId
+//   AerCloud Container: AC_CONTAINER
+//
+// and you'll also need to create an AerCloud contianer with the schema
+// described below
+//
+
+#include "mbed.h"
+#include "mtsas.h"
+#include "HTTPClient.h"
+
+//------------------------------------------------------------------------------------
+// Connectivity Parameters
+//------------------------------------------------------------------------------------
+
+//! Aeris SIM does not use PIN
+#define SIMPIN      NULL
+
+//! The APN of your Aeris SIM
+//    You can find the APN for your SIM at https://aerport.aeris.com
+char _APN[] = "APN_GOES_HERE";
+
+//! User name and password are not required to use Aeris APN
+#define USERNAME    NULL
+
+//! User name and password are not required to use Aeris APN
+#define PASSWORD    NULL
+
+/*
+char _AERCLOUD_API_KEY[] ="_Click_On_KEY_AerCloud_Tab";
+char _AERCLOUD_ACCOUNT_ID[] = "_Company_Number_Top_of_Page";
+char _AERCLOUD_CONTAINER[] = "_From_Container_Page";
+char _AERCLOUD_DEVICE_ID[] = "_Random_Title";
+*/
+
+// ------------------------------------------------------------------------------------
+// AerCloud Paramers
+// ------------------------------------------------------------------------------------
+
+// AerCloud BASE URL
+#define AC_BASE     "http://api.aercloud.aeris.com/v1"
+
+//! AerCloud API Key
+//   You can find your api key at https://aerport.aeris.com"
+#define AC_APIKEY "API_KEY_GOES_HERE"
+
+//! Aercloud Account Id
+//   You can find your account id at https://aerport.aeris.com
+int acId = 0;// ACCOUNT_ID_GOES_HERE
+
+// AerCloud Container
+//  The name of the AerCloud Container to write data into
+#define AC_CONTAINER        "MLT_WORKSHOP_TS"       // Contianer to write Time Series Data
+#define AC_CONTAINER_ALARM  "MLT_WORKSHOP_ALARM"    // Container to write Alarm specific data
+
+//------------------------------------------------------------------------------------
+// AerCloud SCL (Device) Data Model
+// ------------------------------------------------------------------------------------
+//
+// Code assumes an AerCloud Data Model (MLT_WORKSHOP_TS) with following fields
+//
+//  moistureSensorValue     FLOAT       Value read frrom moisture sensor
+//  moistureProcessedValue  FLOAT       Processed value of moisture sensor (LOW / MEDIUM / HIGH)
+//  alcoholSensorValue      FLOAT       Value read frrom alcohol sensor
+//  alcoholProcessedValue   FLOAT       Processed value of alcohol sensor (LOW / MEDIUM / HIGH)
+//  sclid                   INT         Device-id
+//  timeStamp               LONG        timestamp when event occurred
+//
+// Code assumes an AerCloud Data Model (MLT_WORKSHOP_ALARM) with following fields
+//
+//  alarmText           STRING  alarm string
+//  timeStamp           LONG    time at which alarn has been generated
+//  sclid               INT     Device-id
+//
+//------------------------------------------------------------------------------------
+
+
+// Define alcoholSensor and moisture input PIN
+AnalogIn alcoholSensor(A3);
+AnalogIn moisture(A2);
+
+float moistureValue = 0.0f;
+float alcoholValue = 0.0f;
+float moistureProcessedValue = 0.0f;
+float alcoholProcessedValue = 0.0f;
+
+float moistureLastPeakValue = 0.0f;
+float alcoholLastPeakValue = 0.0f;
+
+// Enumeration for sensor
+#define MOISTURE_SENSOR     1
+#define ALCOHOL_SENSOR      2
+
+// Enumeration for Range
+#define LOW     1
+#define MEDIUM  2
+#define HIGH    3
+
+
+char str[512];
+char *simImei;
+
+const char* HttpResultToString(HTTPResult r)
+{
+    switch(r) {
+        case HTTP_PROCESSING:
+            return "HTTP_PROCESSING";
+        case HTTP_PARSE:
+            return "HTTP_PARSE";
+        case HTTP_DNS:
+            return "HTTP_DNS";
+        case HTTP_PRTCL:
+            return "HTTP_PRTCL";
+        case HTTP_NOTFOUND:
+            return "HTTP_NOTFOUND - 404";
+        case HTTP_REFUSED:
+            return "HTTP_REFUSED - 403";
+        case HTTP_ERROR:
+            return "HTTP_ERROR";
+        case HTTP_TIMEOUT:
+            return "HTTP_TIMEOUT";
+        case HTTP_CONN:
+            return "HTTP_CONN";
+        case HTTP_CLOSED:
+            return "HTTP_CLOSED";
+        case HTTP_OK:
+            return "HTTP_OK";
+    }
+
+    return "UNKNOWN ERROR CODE";
+}
+
+//Phone number to send to and receive from. Must be in the form "1xxxxxxxxxx"
+string PHONE_NUMBER = "CHANGE ME PLEASE";
+
+int main()
+{
+    bool simProvisioned = false;
+    int ret;
+
+    printf("Dragon Fly Sample Program for MultiTech Connected Cooler ...\n\r");
+
+    //Sets the log level to INFO, higher log levels produce more log output.
+    //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE
+    MTSLog::setLogLevel(MTSLog::TRACE_LEVEL);
+
+    /** STMicro Nucelo F411RE
+    * The supported jumper configurations of the MTSAS do not line up with
+    * the pin mapping of the Nucleo F411RE. Therefore, the MTSAS serial TX
+    * pin (JP8 Pin 2) must be manually jumped to Serial1 RX (Shield pin D2)
+    * and the MTSAS serial RX pin (JP9 Pin 2) pin must be manually jumped to
+    * Serial1 TX (Shield pin D8).
+    */
+    printf("Before initiating io");
+    MTSSerialFlowControl* io = new MTSSerialFlowControl(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS);
+    printf("After initiating io");
+
+    //Sets the baud rate for communicating with the radio
+    io->baud(115200);
+    printf("*****1*********");
+
+    //Creates a radio object
+    Cellular* radio = CellularFactory::create(io);
+    printf("*****2*********");
+
+    if (! radio) {
+        logFatal("failed to create Cellular object - exiting");
+        printf("failed to create Cellular object - exiting.\n\r");
+        return 1;
+    }
+    printf("*****3*********");
+
+    radio->configureSignals(D11,D7,RESET);          // Modified Flow Control for ST Sensor Board  D11
+    printf("*****4*********");
+
+    Transport::setTransport(radio);                 // Required to control Cell Radio vs WiFi solution
+    printf("*****5*********");
+
+    while (radio->setApn(_APN) != MTS_SUCCESS) {
+        logError("failed to set APN [%s]", _APN);
+        printf("failed to set APN.\n\r");
+        wait(2);
+    }
+    printf("*****6*********");
+
+    while (! radio->connect()) {
+        logError("failed to bring up PPP link");
+        printf("failed to bring up PPP link.\n\r");
+        wait(2);
+    }
+    printf("*****7*********");
+
+    printf("Signal Strength: %d\n\r", radio->getSignalStrength()); //Check the signal strength should be above 8
+
+    // If you suspect a connectivity issue, uncomment the code below and if ping works.  If you are not getting a
+    //  valid ping, there's a connectivity problem.  First step is to verify you've got the right APN set
+    //
+    // Try pinging default server "8.8.8.8" (Google's DNS)
+    int ping_valid = 0;
+    while (ping_valid == 0) {
+        ping_valid = radio->ping();
+        // or can use ping_valid = radio->ping("www.google.com");
+        printf("Ping Valid: %s\n\r", ping_valid ? "true" : "false");
+
+        if (ping_valid == 0) {
+            wait(3);
+            printf("wait 3");
+            //  wait(33);
+        }
+    }
+
+    // Get the IMEI of the SIM, this will act as SCL-id on AerCloud
+    string sImei;
+    sImei = radio->getEquipmentIdentifier();
+    simImei = (char*) sImei.c_str();
+
+    // Create http client
+    HTTPClient http;
+
+    // Check if SIM is provisioned in AerCloud
+    printf("\r\nIs the SIM provisioned?  ");
+    char url[512];
+    snprintf(url, sizeof(url), "%s/%d/scls/%s?apiKey=%s", AC_BASE, acId, simImei, AC_APIKEY);
+    ret = http.get(url, str, 128);
+    printf("URL : %s", url);
+    printf("STR : %s", str);
+
+    if (ret == HTTP_OK) {
+        // We're already provisioned
+        printf("Yes\r\n");
+        printf("Page fetched successfully - read %d characters\r\n", strlen(str));
+        printf("Result: %s\r\n", str);
+        simProvisioned = true;
+    } else {
+        printf("No\r\n");
+        printf("Error - ret = %d - HTTP return code = %d\r\n", ret, http.getHTTPResponseCode());
+
+        //SIM is not provisioned. trying to provision it...
+        char url[512];
+        snprintf(url, sizeof(url), "%s/%d/scls?apiKey=%s", AC_BASE, acId, AC_APIKEY);
+        snprintf(str, sizeof(str), "{\"sclId\":\"%s\"}\0",simImei);
+        HTTPText outText(str);
+        HTTPText inText(str, 512);
+        ret = http.post(url, outText, &inText);
+
+        if (!ret) {
+            printf("Executed POST successfully - read %d characters\r\n", strlen(str));
+            printf("Result: %s\r\n", str);
+            simProvisioned = true;
+        } else {
+            if(http.getHTTPResponseCode() == 200)
+                simProvisioned = true;
+            printf("Error - ret = %d - HTTP return code = %d\r\n", ret, http.getHTTPResponseCode());
+        }
+    }
+
+    //POST data to containers if SIM has been successfully provisioned
+    if (simProvisioned) {
+        while(1) {
+
+            // Read data from sensor
+            char alarmStringM[512] = "";
+            bool generateAlertM = false;
+
+            moistureValue = moisture;
+            printf("Moisture value read : %f \n\n",moistureValue);
+            if (moistureValue > .5f) {
+                moistureProcessedValue = HIGH;
+            } else if (moistureValue > .25f) {
+                moistureProcessedValue = MEDIUM;
+            } else {
+                moistureProcessedValue = LOW;
+            }
+
+            if (moistureLastPeakValue != moistureProcessedValue) {  //condition to trigger alarm
+                if (moistureLastPeakValue == 0) {                   // first time
+                    moistureLastPeakValue = moistureProcessedValue;
+                    generateAlertM = false;
+                } else {
+                    if (moistureLastPeakValue == LOW) {
+                        if (moistureProcessedValue == MEDIUM) {
+                            strcpy (alarmStringM, "Moisture level going up from LOW to MEDIUM");
+                        } else if (moistureProcessedValue == HIGH) {
+                            strcpy (alarmStringM, "Moisture level going up from LOW to HIGH");
+                        }
+                    } else if (moistureLastPeakValue == MEDIUM) {
+                        if (moistureProcessedValue == LOW) {
+                            strcpy (alarmStringM, "Moisture level going down from MEDIUM to LOW");
+                        } else if (moistureProcessedValue == HIGH) {
+                            strcpy (alarmStringM, "Moisture level going up from MEDIUM to HIGH");
+                        }
+                    } else if (moistureLastPeakValue == HIGH) {
+                        if (moistureProcessedValue == LOW) {
+                            strcpy (alarmStringM, "Moisture level going down from HIGH to LOW");
+                        } else if (moistureProcessedValue == MEDIUM) {
+                            strcpy (alarmStringM, "Moisture level going down from HIGH to MEDIUM");
+                        }
+                    }
+                    moistureLastPeakValue = moistureProcessedValue;
+                    generateAlertM = true;
+                }
+            }
+            
+            char alarmStringA[512] = "";
+            bool generateAlertA = false;
+
+            alcoholValue = 1 - alcoholSensor; // as per example logic value needs to be subtracted from 1 (inverse value)
+            printf("Alcohol value read : %f \n\n",alcoholValue);
+            if (alcoholValue > .5f) {
+                alcoholProcessedValue = HIGH;
+            } else if (alcoholValue > .25f) {
+                alcoholProcessedValue = MEDIUM;
+            } else {
+                alcoholProcessedValue = LOW;
+            }
+
+            if (alcoholLastPeakValue != alcoholProcessedValue) {  //condition to trigger alarm
+                if (alcoholLastPeakValue == 0) {                   // first time
+                    alcoholLastPeakValue = alcoholProcessedValue;
+                    generateAlertA = false;
+                } else {
+                    if (alcoholLastPeakValue == LOW) {
+                        if (alcoholProcessedValue == MEDIUM) {
+                            strcpy (alarmStringA, "Alcohol level going up from LOW to MEDIUM");
+                        } else if (alcoholProcessedValue == HIGH) {
+                            strcpy (alarmStringA, "Alcohol level going up from LOW to HIGH");
+                        }
+                    } else if (alcoholLastPeakValue == MEDIUM) {
+                        if (alcoholProcessedValue == LOW) {
+                            strcpy (alarmStringA, "Alcohol level going down from MEDIUM to LOW");
+                        } else if (alcoholProcessedValue == HIGH) {
+                            strcpy (alarmStringA, "Alcohol level going up from MEDIUM to HIGH");
+                        }
+                    } else if (alcoholLastPeakValue == HIGH) {
+                        if (alcoholProcessedValue == LOW) {
+                            strcpy (alarmStringA, "Alcohol level going down from HIGH to LOW");
+                        } else if (alcoholProcessedValue == MEDIUM) {
+                            strcpy (alarmStringA, "Alcohol level going down from HIGH to MEDIUM");
+                        }
+                    }
+                    alcoholLastPeakValue = alcoholProcessedValue;
+                    generateAlertA = true;
+                }
+            }
+ 
+            // POST data to AerCLoud
+            char url[512];
+            time_t seconds = time(NULL);
+            snprintf(url, sizeof(url), "%s/%d/scls/%s/containers/%s/contentInstances?apiKey=%s", AC_BASE, acId, simImei, AC_CONTAINER, AC_APIKEY);
+            sprintf(str,"{\"moistureSensorValue\": %.5f, \"moistureProcessedValue\": %.5f, \"alcoholSensorValue\": %.5f, \"alcoholProcessedValue\": %.5f, \"sclId\":\"%s\", \"timeStamp\": %u}", moistureValue, moistureProcessedValue, alcoholValue, alcoholProcessedValue, simImei, seconds);
+
+            // Evt Source M=1, A=2 -- post moisture
+            // sprintf(str,"{\"eventSource\": %d, \"eventRawValue\": %.5f, \"eventProcessedValue\": %.5f, \"sclId\":\"%s\", \"timeStamp\": %u}", MOISTURE_SENSOR, moistureValue, moistureProcessedValue, simImei, seconds);
+            printf("Url = %s \r\n",url);
+            printf("str = %s \r\n",str);
+            HTTPText outText(str);
+            HTTPText inText(str, 512);
+            printf("\r\nPost acquired data...\r\n");
+            ret = http.post(url, outText, &inText);
+            if (ret == HTTP_OK) {
+                printf("Executed POST successfully - read %d characters\r\n", strlen(str));
+                printf("Result: %s\r\n", str);
+            } else {
+                printf("Error - ret = %d (%s), - HTTP return code = %d\r\n", ret, HttpResultToString((HTTPResult)ret), http.getHTTPResponseCode());
+            }
+            
+/*
+            // Evt Source M=1, A=2 -- Now post Alcohol
+            sprintf(str,"{\"eventSource\": %d, \"eventRawValue\": %.5f, \"eventProcessedValue\": %.5f, \"sclId\":\"%s\", \"timeStamp\": %u}", ALCOHOL_SENSOR, alcoholValue, alcoholProcessedValue, simImei, seconds);
+            printf("Url = %s \r\n",url);
+            printf("str = %s \r\n",str);
+
+            HTTPText outText2(str);
+            HTTPText inText2(str, 512);
+            printf("\r\nPost acquired data...\r\n");
+            ret = http.post(url, outText2, &inText2);
+            if (ret == HTTP_OK) {
+                printf("Executed POST successfully - read %d characters\r\n", strlen(str));
+                printf("Result: %s\r\n", str);
+            } else {
+                printf("Error - ret = %d (%s), - HTTP return code = %d\r\n", ret, HttpResultToString((HTTPResult)ret), http.getHTTPResponseCode());
+            }
+*/
+            // post alert for Moisture
+            if (generateAlertM) {
+                snprintf(url, sizeof(url), "%s/%d/scls/%s/containers/%s/contentInstances?apiKey=%s", AC_BASE, acId, simImei, AC_CONTAINER_ALARM, AC_APIKEY);
+                sprintf(str,"{\"alarmText\": %s, \"sclId\":\"%s\", \"timeStamp\": %u}", alarmStringM, simImei, seconds);
+                printf("Url = %s \r\n",url);
+                printf("str = %s \r\n",str);
+    
+                HTTPText outText(str);
+                HTTPText inText(str, 512);
+                printf("\r\nPost acquired data...\r\n");
+                ret = http.post(url, outText, &inText);
+                if (ret == HTTP_OK) {
+                    printf("Executed POST successfully - read %d characters\r\n", strlen(str));
+                    printf("Result: %s\r\n", str);
+                } else {
+                    printf("Error - ret = %d (%s), - HTTP return code = %d\r\n", ret, HttpResultToString((HTTPResult)ret), http.getHTTPResponseCode());
+                }
+            }
+            
+            // post alert for Alcohol
+            if (generateAlertA) {
+                snprintf(url, sizeof(url), "%s/%d/scls/%s/containers/%s/contentInstances?apiKey=%s", AC_BASE, acId, simImei, AC_CONTAINER_ALARM, AC_APIKEY);
+                sprintf(str,"{\"alarmText\": %s, \"sclId\":\"%s\", \"timeStamp\": %u}", alarmStringA, simImei, seconds);
+                printf("Url = %s \r\n",url);
+                printf("str = %s \r\n",str);
+    
+                HTTPText outText(str);
+                HTTPText inText(str, 512);
+                printf("\r\nPost acquired data...\r\n");
+                ret = http.post(url, outText, &inText);
+                if (ret == HTTP_OK) {
+                    printf("Executed POST successfully - read %d characters\r\n", strlen(str));
+                    printf("Result: %s\r\n", str);
+                } else {
+                    printf("Error - ret = %d (%s), - HTTP return code = %d\r\n", ret, HttpResultToString((HTTPResult)ret), http.getHTTPResponseCode());
+                }
+            }
+
+            printf("Will be measuring again after 100 milli seconds !!!! \r\n\n");
+            wait_ms (100);
+        }
+    }
+
+    //Disconnect ppp link of radio
+    radio->disconnect();
+}
+
+/*
+    // Logic to read peak value from moisture sensor
+    moistureValue = 0;
+    int i=0;
+    do {
+        float readFromSensor = moisture;
+        if ( readFromSensor > moistureValue)
+            moistureValue = readFromSensor;
+        printf("Moisture - Current value read from sensor: %f \n\n",readFromSensor);
+        wait_ms (100);  // wait for 100ms
+        i++;
+    } while (moistureValue < 0.1 && i<100);
+
+    printf("Moisture - Value get posted to AerCloud: %f \n\n",moistureValue);
+*/
\ No newline at end of file