Raghu Tirumala / Mbed OS ATT_IoT_Project

Dependencies:   BufferedSoftSerial SDFileSystem

Fork of ATT_AWS_IoT_demo by AT&T IoT

Revision:
29:319446cd2880
Parent:
28:d549de7c3aad
Child:
30:d2a7e413f658
Child:
31:dc2541e12a1a
--- a/main.cpp	Mon Jul 17 12:03:23 2017 +0000
+++ b/main.cpp	Mon Jul 31 22:45:26 2017 +0000
@@ -44,25 +44,25 @@
 // Comment out the following line if color is not supported on the terminal
 //#define USE_COLOR
 #ifdef USE_COLOR
- #define BLK "\033[30m"
- #define RED "\033[31m"
- #define GRN "\033[32m"
- #define YEL "\033[33m"
- #define BLU "\033[34m"
- #define MAG "\033[35m"
- #define CYN "\033[36m"
- #define WHT "\033[37m"
- #define DEF "\033[39m"
+#define BLK "\033[30m"
+#define RED "\033[31m"
+#define GRN "\033[32m"
+#define YEL "\033[33m"
+#define BLU "\033[34m"
+#define MAG "\033[35m"
+#define CYN "\033[36m"
+#define WHT "\033[37m"
+#define DEF "\033[39m"
 #else
- #define BLK
- #define RED
- #define GRN
- #define YEL
- #define BLU
- #define MAG
- #define CYN
- #define WHT
- #define DEF
+#define BLK
+#define RED
+#define GRN
+#define YEL
+#define BLU
+#define MAG
+#define CYN
+#define WHT
+#define DEF
 #endif
 
 // Sensor defines
@@ -76,9 +76,6 @@
 // Controls LED color
 unsigned char ledColor = COLOR_OFF;
 
-//Controls LCD message
-string lcdMessage = "hola";
-
 // These defines are pulled from aws_iot_config.h
 char HostAddress[255] = AWS_IOT_MQTT_HOST;
 char MqttClientID[32] = AWS_IOT_MQTT_CLIENT_ID;
@@ -97,6 +94,9 @@
 //Variable to store data usage
 int dataUsage = 0;
 
+//slave JSON to publish
+string slaveJSON = "";
+
 //=====================================================================================================================
 //
 // Devices
@@ -134,42 +134,16 @@
 
 //*********************************************************************************************************************
 //* Set the RGB LED's Color
-//* LED Color 0=Off to 7=White.  3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue) 
+//* LED Color 0=Off to 7=White.  3 bits represent BGR (bit0=Red, bit1=Green, bit2=Blue)
 //*********************************************************************************************************************
 void SetLedColor(unsigned char ucColor)
-{    
+{
     //Note that when an LED is on, you write a 0 to it:
     led_red = !(ucColor & 0x1); //bit 0
     led_green = !(ucColor & 0x2); //bit 1
     led_blue = !(ucColor & 0x4); //bit 2
 }
 
-//*********************************************************************************************************************
-//* Print LED and sensor data
-//*********************************************************************************************************************
-void printData()
-{
-    INFO("Temperature is: %0.2f F", temperature);
-    INFO("Humidity    is: %0.2f %", humidity);      
-    switch (ledColor) {
-         case COLOR_OFF:
-             INFO("LED: Off");
-             break;
-         case COLOR_RED:
-             INFO("LED: Red");
-             break;
-         case COLOR_GREEN:
-             INFO("LED: Green");
-             break;
-         case COLOR_BLUE:
-             INFO("LED: Blue");
-             break;
-         case COLOR_WHITE:
-             INFO("LED: White");
-             break;
-    }
-}
-
 //=====================================================================================================================
 //
 // AWS Shadow Callbacks
@@ -179,10 +153,11 @@
 //* This is the callback function that fires when an update is sent.  It will print the update response status.
 //*********************************************************************************************************************
 void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
-        const char *pReceivedJsonDocument, void *pContextData) {
+                                const char *pReceivedJsonDocument, void *pContextData)
+{
 
     INFO("Shadow Update Status Callback");
-    
+
     if (status == SHADOW_ACK_TIMEOUT) {
         INFO("Update Timeout--");
     } else if (status == SHADOW_ACK_REJECTED) {
@@ -193,14 +168,15 @@
 }
 
 //*********************************************************************************************************************
-//* These are the callback functions that fire when AWS has sends out a shadow update. 
+//* These are the callback functions that fire when AWS has sends out a shadow update.
 //*********************************************************************************************************************
-void ledControl_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
-    
+void ledControl_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext)
+{
+
     INFO("LED Callback Detected.");
-    
+
     if (pContext != NULL) {
-        switch (*(unsigned char *)(pContext->pData)){   
+        switch (*(unsigned char *)(pContext->pData)) {
             case COLOR_OFF:
                 INFO("LED -> OFF (%d)", *(unsigned char *)(pContext->pData));
                 break;
@@ -215,41 +191,27 @@
                 break;
             case COLOR_WHITE:
                 INFO("LED -> WHITE (%d)", *(unsigned char *)(pContext->pData));
-                break;    
+                break;
         }
-    }
-    else {
+    } else {
         INFO("pContext was detected as NULL");
     }
 }
-
-//This callback handles changing the lcdMEssage field that is sent to the slave device
-void lcdControl_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
-    INFO("LCD Callback detected");
-    INFO("LCD String is %s", (char *) (pContext->pData));
-    if(pJsonString != NULL) {
-        int index = 0;
-        while(pJsonString != NULL && pJsonString[index] != '"') {
-            index++;    
-        }
-        string tempString(pJsonString, pJsonString + index);
-        lcdMessage.assign(tempString);
-    }
-}
-
 //Callback when dataUsage stats are updated
-void dataUsageCallback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
-    INFO("Data usage callback detected");    
+void dataUsageCallback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext)
+{
+    INFO("Data usage callback detected");
 }
 //*********************************************************************************************************************
 //* Subscribe callback (used with alternate demo)
 //*********************************************************************************************************************
-int MQTTcallbackHandler(MQTTCallbackParams params) {
+int MQTTcallbackHandler(MQTTCallbackParams params)
+{
 
     INFO("Subscribe callback");
     INFO("%.*s\t%.*s",
-            (int)params.TopicNameLen, params.pTopicName,
-            (int)params.MessageParams.PayloadLen, (char*)params.MessageParams.pPayload);
+         (int)params.TopicNameLen, params.pTopicName,
+         (int)params.MessageParams.PayloadLen, (char*)params.MessageParams.pPayload);
 
     return 0;
 }
@@ -257,31 +219,142 @@
 //*********************************************************************************************************************
 //* Disconnect handling (used with alternate demo)
 //*********************************************************************************************************************
-void disconnectCallbackHandler(void) {
+void disconnectCallbackHandler(void)
+{
     WARN("MQTT Disconnect");
     IoT_Error_t rc = NONE_ERROR;
-    if(aws_iot_is_autoreconnect_enabled()){
+    if(aws_iot_is_autoreconnect_enabled()) {
         INFO("Auto Reconnect is enabled, Reconnecting attempt will start now");
-    }else{
+    } else {
         WARN("Auto Reconnect not enabled. Starting manual reconnect...");
         rc = aws_iot_mqtt_attempt_reconnect();
-        if(RECONNECT_SUCCESSFUL == rc){
+        if(RECONNECT_SUCCESSFUL == rc) {
             WARN("Manual Reconnect Successful");
-        }else{
+        } else {
             WARN("Manual Reconnect Failed - %d", rc);
         }
     }
 }
 
 //*********************************************************************************************************************
-//* Send LCD message over bluetooth interface
+//* Get slave data over uart interface
 //*********************************************************************************************************************
-void setLCDMessage(string str) {
-    bluetooth.putc('*');
-    for(int i = 0; i < str.length(); i++) {
-        bluetooth.putc(str.at(i));    
-    }    
-    bluetooth.putc('\n');
+void getSlaveJSON()
+{
+    if(bluetooth.writeable()) {
+        bluetooth.putc('d');
+    }
+    slaveJSON = "";
+    while(bluetooth.readable()) {
+        slaveJSON += bluetooth.getc();
+    }
+}
+
+//=====================================================================================================================
+//
+// Out-of-Box Demo: This function is used as part of the binary that comes with the Starter Kit.  Instead of using an
+//                  AWS device shadow, it publishes to an AWS Rule. The Rule is setup to store data to a DynamoDB, and
+//                  the demo S3 website pulls that data from the DynamoDB and displays it.
+//
+//=====================================================================================================================
+int outOfBoxDemo()
+{
+    INFO("Running Out-of-Box Function (alternate demo).");
+
+    IoT_Error_t rc = NONE_ERROR;
+    int32_t i = 0;
+    int publishCount = 0;
+    bool infinitePublishFlag = true;
+    char cPayload[100];
+    char cTopic[100];
+    float updateInterval = 3.0; // seconds
+
+    MQTTConnectParams connectParams = MQTTConnectParamsDefault;
+    connectParams.KeepAliveInterval_sec = 10;
+    connectParams.isCleansession = true;
+    connectParams.MQTTVersion = MQTT_3_1_1;
+    connectParams.pClientID = iccidName;  // Using ICCID for unique Client ID
+    connectParams.pHostURL = HostAddress;
+    connectParams.port = port;
+    connectParams.isWillMsgPresent = false;
+    connectParams.pRootCALocation = AWS_IOT_ROOT_CA_FILENAME;
+    connectParams.pDeviceCertLocation = AWS_IOT_CERTIFICATE_FILENAME;
+    connectParams.pDevicePrivateKeyLocation = AWS_IOT_PRIVATE_KEY_FILENAME;
+    connectParams.mqttCommandTimeout_ms = 10000;
+    connectParams.tlsHandshakeTimeout_ms = 10000;
+    connectParams.isSSLHostnameVerify = true; // ensure this is set to true for production
+    connectParams.disconnectHandler = disconnectCallbackHandler;
+
+    INFO("Connecting...");
+    rc = aws_iot_mqtt_connect(&connectParams);
+    if (NONE_ERROR != rc) {
+        ERROR("Error(%d) connecting to %s:%d", rc, connectParams.pHostURL, connectParams.port);
+    }
+
+    /*
+     * Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
+     *  #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
+     *  #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
+     */
+    INFO("Set Auto Reconnect...");
+    rc = aws_iot_mqtt_autoreconnect_set_status(true);
+    if (NONE_ERROR != rc) {
+        ERROR("Unable to set Auto Reconnect to true - %d", rc);
+        return rc;
+    }
+
+    // Initialize the payload
+    MQTTMessageParams Msg = MQTTMessageParamsDefault;
+    Msg.qos = QOS_0;
+    Msg.pPayload = (void *) cPayload;
+
+    MQTTPublishParams Params = MQTTPublishParamsDefault;
+
+    // Sets up the topic to publish to
+    sprintf(cTopic, AWS_IOT_MY_TOPIC, iccidName);
+    Params.pTopic = cTopic;
+
+    if (publishCount != 0) {
+        infinitePublishFlag = false;
+    }
+
+    while ((NETWORK_ATTEMPTING_RECONNECT == rc || RECONNECT_SUCCESSFUL == rc || NONE_ERROR == rc)
+            && (publishCount > 0 || infinitePublishFlag)) {
+
+        // Max time the yield function will wait for read messages
+        rc = aws_iot_mqtt_yield(100);
+        if(NETWORK_ATTEMPTING_RECONNECT == rc) {
+            INFO("--> sleep (attempting to reconnect)");
+            wait(1);
+            // If the client is attempting to reconnect we will skip the rest of the loop.
+            continue;
+        }
+
+        getSlaveJSON();
+        INFO("%s", slaveJSON);
+        // Loading data into JSON format
+        sprintf(cPayload, "Data");
+        Msg.PayloadLen = strlen(cPayload) + 1;
+        Params.MessageParams = Msg;
+
+        // Publish
+        rc = aws_iot_mqtt_publish(&Params);
+        if (publishCount > 0) {
+            publishCount--;
+        }
+
+        INFO("--> Update sent. Sleep for %f seconds", updateInterval);
+        wait(updateInterval-.02);
+    }
+
+
+    if (NONE_ERROR != rc) {
+        ERROR("An error occurred in the loop.\n");
+    } else {
+        INFO("Publish done\n");
+    }
+
+    return rc;
 }
 
 //=====================================================================================================================
@@ -289,62 +362,36 @@
 // Main
 //
 //=====================================================================================================================
-int main() {
+int main()
+{
     // Set baud rate for PC Serial
     pc.baud(115200);
     bluetooth.baud(9600);
     INFO("Program Start");
-               
-    IoT_Error_t rc = NONE_ERROR;  
+
+    IoT_Error_t rc = NONE_ERROR;
     char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
     size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);
 
-    // JSON struct for LED control
-    jsonStruct_t ledController;
-    ledController.cb = ledControl_Callback;
-    ledController.pData = &ledColor;
-    ledController.pKey = "ledColor";
-    ledController.type = SHADOW_JSON_UINT8;
-    
-    // JSON struct for LCD control
-    jsonStruct_t lcdController;
-    lcdController.cb = lcdControl_Callback;
-    lcdController.pData = &lcdMessage[0u];
-    lcdController.pKey = "lcdMessage";
-    lcdController.type = SHADOW_JSON_STRING;
-    
-    // JSON struct for temperature\humidity readings
-    jsonStruct_t temperatureHandler;
-    temperatureHandler.cb = NULL;
-    temperatureHandler.pKey = "temperature";
-    temperatureHandler.pData = &temperature;
-    temperatureHandler.type = SHADOW_JSON_FLOAT;
-    
-    jsonStruct_t humidityHandler;
-    humidityHandler.cb = NULL;
-    humidityHandler.pKey = "humidity";
-    humidityHandler.pData = &humidity;
-    humidityHandler.type = SHADOW_JSON_FLOAT;
-
     //JSON struct for signal strength readings
     jsonStruct_t signalStrengthHandler;
     signalStrengthHandler.cb = NULL;
     signalStrengthHandler.pKey = "Signal Strength";
     signalStrengthHandler.pData = &signalQuality;
     signalStrengthHandler.type = SHADOW_JSON_INT16;
-    
-    //JSON struct for data usage 
+
+    //JSON struct for data usage
     jsonStruct_t dataUsageHandler;
     dataUsageHandler.cb = dataUsageCallback;
     dataUsageHandler.pKey = "Data Usage";
     dataUsageHandler.pData = &dataUsage;
     dataUsageHandler.type = SHADOW_JSON_UINT32;
-    
+
     INFO("AWS IoT SDK Version(dev) %d.%d.%d-%s", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
 
 
-    INFO("Using #defines in aws_iot_config.h and certs from certs.cpp for AWS config.");      
-    
+    INFO("Using #defines in aws_iot_config.h and certs from certs.cpp for AWS config.");
+
     // Startup signal - blinks through RGBW then turns off
     SetLedColor(COLOR_RED);
     wait(.5);
@@ -355,11 +402,14 @@
     SetLedColor(COLOR_WHITE);
     wait(.5);
     SetLedColor(COLOR_OFF);
-      
+
     // Boot the Avnet Shield before any other operations
     INFO("Net Boot...");
     net_modem_boot();
-       
+    
+    outOfBoxDemo();
+    return;
+    
     // Intialize MQTT/Cert parameters
     ShadowParameters_t sp = ShadowParametersDefault;
 #ifdef USING_SD_CARD
@@ -367,7 +417,7 @@
     if (NONE_ERROR != rc) {
         ERROR("Failed to initialize mqtt parameters %d", rc);
         return rc;
-    }   
+    }
     sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
     sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
     sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
@@ -376,24 +426,24 @@
     sp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
     sp.pHost = HostAddress;
     sp.port = port;
-    
+
     sp.pClientCRT = AWS_IOT_CERTIFICATE_FILENAME;
     sp.pClientKey = AWS_IOT_PRIVATE_KEY_FILENAME;
     sp.pRootCA = AWS_IOT_ROOT_CA_FILENAME;
 #endif
-         
+
     INFO("Initialize the MQTT client...");
     MQTTClient_t mqttClient;
     aws_iot_mqtt_init(&mqttClient);
-    
+
     INFO("Shadow Init...");
     rc = aws_iot_shadow_init(&mqttClient);
     if (NONE_ERROR != rc) {
         ERROR("Shadow Init Error %d", rc);
         return rc;
     }
-    
-    INFO("Shadow Connect...");   
+
+    INFO("Shadow Connect...");
     rc = aws_iot_shadow_connect(&mqttClient, &sp);
     if (NONE_ERROR != rc) {
         ERROR("Shadow Connection Error %d", rc);
@@ -403,24 +453,14 @@
     // Enable Auto Reconnect functionality. Minimum and Maximum time of Exponential backoff are set in aws_iot_config.h
     // #AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL
     // #AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
-    
+
     rc = mqttClient.setAutoReconnectStatus(true);
     if (NONE_ERROR != rc) {
         ERROR("Unable to set Auto Reconnect to true - %d", rc);
         return rc;
     }
-        
+
     INFO("Shadow Register Delta...");
-    rc = aws_iot_shadow_register_delta(&mqttClient, &ledController);
-    if (NONE_ERROR != rc) {
-        ERROR("Shadow Register Delta led Error");
-        return rc;
-    }
-    rc = aws_iot_shadow_register_delta(&mqttClient, &lcdController);
-    if (NONE_ERROR != rc) {
-        ERROR("Shadow Register Delta lcd Error");
-        return rc;
-    }
     rc = aws_iot_shadow_register_delta(&mqttClient, &dataUsageHandler);
     if (NONE_ERROR != rc) {
         ERROR("Shadow Register Delta dataUsage Error");
@@ -440,72 +480,28 @@
         }
         //Read signal quality
         signalQuality = WNCInterface::_pwnc->getDbmRssi();
-        
-        // Read sensor data
-        if(bluetooth.writeable()) {
-            bluetooth.putc('t'); //request for sensor data
-        } else {
-            INFO("Can't write to bluetooth");   
-        }
-        
-        //parse incoming sensor data
-        string resultTemp = "";
-        string resultHum = "";
-        string * result = &resultTemp;
-        while(bluetooth.readable()) {
-            int c = bluetooth.getc(); 
-            char ch = static_cast<char>(c); 
-            if(ch == '\n') {
-                result = &resultHum;    
-            }
-            *result += ch;            
-        }
-                
-        temperature = CTOF(atof(resultTemp.c_str()));
-        humidity = atof(resultHum.c_str());
-                          
-        INFO("\n=======================================================================================\n");             
-        // Initialize JSON shadow document          
+
+        INFO("\n=======================================================================================\n");
+        // Initialize JSON shadow document
         rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
         if (rc == NONE_ERROR) {
-            
+
             // Updates the 'reported' color/temp/humidity
-            rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 4, &ledController,
-                                                                                              &lcdController,
-                                                                                              &signalStrengthHandler,
-                                                                                              &dataUsageHandler);
-                 
-            if (rc == NONE_ERROR) {               
-                rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);   
-                            
+            rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 2, &signalStrengthHandler,
+                                             &dataUsageHandler);
+
+            if (rc == NONE_ERROR) {
+                rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
+
                 if (rc == NONE_ERROR) {
                     INFO("Update Shadow: %s", JsonDocumentBuffer);
                     rc = aws_iot_shadow_update(&mqttClient, sp.pMyThingName, JsonDocumentBuffer,
-                            ShadowUpdateStatusCallback, NULL, 15, true);
+                                               ShadowUpdateStatusCallback, NULL, 15, true);
                 }
             }
-        }  
-        /*
-        // Loading data into JSON format
-        sprintf(cPayload, "{\"color\":\"%s\",\"temperature\":%f,\"humidity\":%f}", colorStrings[ledColor], temperature, humidity);
-        Msg.PayloadLen = strlen(cPayload) + 1;
-        Params.MessageParams = Msg;
-            
-        // Publish
-        rc = aws_iot_mqtt_publish(&Params);
-        if (publishCount > 0) {
-          publishCount--;
         }
-        */
-        // Print data    
-        printData();
-        INFO("*****************************************************************************************");
-         
-        // Set the LED color    
-        SetLedColor(ledColor);
-        
-        //Set lcd message
-        setLCDMessage(lcdMessage);
+        getSlaveJSON();
+        INFO("%s" , slaveJSON);
         wait(SHADOW_SYNC_INTERVAL);
     }
 
@@ -520,5 +516,5 @@
         ERROR("Disconnect error %d", rc);
     }
 
-    return rc;   
+    return rc;
 }
\ No newline at end of file