Raghu Tirumala / Mbed OS ATT_IoT_Project

Dependencies:   BufferedSoftSerial SDFileSystem

Fork of ATT_AWS_IoT_demo by AT&T IoT

Revision:
28:d549de7c3aad
Parent:
24:224c07ec3bd0
Child:
29:319446cd2880
--- a/main.cpp	Tue Feb 07 16:18:57 2017 +0000
+++ b/main.cpp	Mon Jul 17 12:03:23 2017 +0000
@@ -1,17 +1,15 @@
-/*
- *  AT&T IoT Starter Kit example using Amazon Web Service 
- */
+#include <cstdlib>
 #include "mbed.h"
 
-// SD File System
-#include "SDFileSystem.h"
-
 // Serial extension
 #include "MODSERIAL.h"
+#include "SoftSerial.h"
+#include "BufferedSoftSerial.h"
 
 // Network includes
 #include "WNCInterface.h"
 #include "network_interface.h"
+#include "WncControllerK64F/WncController/WncController.h"
 
 // AWS includes
 #include "aws_iot_log.h"
@@ -21,9 +19,6 @@
 #include "aws_iot_config.h"
 #include "aws_iot_mqtt_interface.h"
 
-// Sensors
-#include "HTS221.h"
-
 #if DEBUG_LEVEL > 0
 #include "mbedtls/debug.h"
 #endif
@@ -43,7 +38,7 @@
 
 // AWS defines
 #define PATH_MAX    1024
-#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200 // NOTE: Be wary of this if your JSON doc grows
+#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 500 // NOTE: Be wary of this if your JSON doc grows
 #define SHADOW_SYNC_INTERVAL 3.0             // How often we sync with AWS Shadow (in seconds)
 
 // Comment out the following line if color is not supported on the terminal
@@ -81,12 +76,8 @@
 // Controls LED color
 unsigned char ledColor = COLOR_OFF;
 
-// Color cycle array (used with SW3 button presses)
-unsigned char colorCycle[NUM_COLORS] = {COLOR_OFF, COLOR_RED, COLOR_GREEN, COLOR_BLUE, COLOR_WHITE};
-
-// Button interrupts
-bool buttonOverride = false;
-InterruptIn Interrupt(SW3);
+//Controls LCD message
+string lcdMessage = "hola";
 
 // These defines are pulled from aws_iot_config.h
 char HostAddress[255] = AWS_IOT_MQTT_HOST;
@@ -98,10 +89,13 @@
 
 // Sensor data
 float temperature = 0.0;
-int   humidity    = 0;
+float   humidity    = 0.0;
 
-// Temp/humidity object
-HTS221 hts221; 
+//Cell signal
+int signalQuality = 0;
+
+//Variable to store data usage
+int dataUsage = 0;
 
 //=====================================================================================================================
 //
@@ -116,8 +110,8 @@
 // USB Serial port (to PC)
 MODSERIAL pc(USBTX,USBRX,256,256);
 
-// SD card access (MOSI, MISO, SCK, CS)
-SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd");
+// Bluetooth serial
+BufferedSoftSerial bluetooth(PTC4, PTA2);
 
 // I2C bus (SDA, SCL)
 I2C i2c(PTC11, PTC10);
@@ -151,32 +145,12 @@
 }
 
 //*********************************************************************************************************************
-//* SW3 Button handler.  Finds the current LED color and sets the button to the next color in colorCycle[]
-//*********************************************************************************************************************
-void sw3ButtonHandler()
-{
-    int i;
-    for(i=0; i < NUM_COLORS; i++) {
-        if (ledColor == colorCycle[i])
-            break;
-    }
-    
-    // (circular-queue)
-    if (++i == NUM_COLORS)
-        i = 0;
-        
-    ledColor = colorCycle[i];
-    SetLedColor(ledColor);
-    buttonOverride = true;
-}
-
-//*********************************************************************************************************************
 //* Print LED and sensor data
 //*********************************************************************************************************************
 void printData()
 {
     INFO("Temperature is: %0.2f F", temperature);
-    INFO("Humidity    is: %02d", humidity);      
+    INFO("Humidity    is: %0.2f %", humidity);      
     switch (ledColor) {
          case COLOR_OFF:
              INFO("LED: Off");
@@ -219,7 +193,7 @@
 }
 
 //*********************************************************************************************************************
-//* This is the callback function that fires 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) {
     
@@ -248,7 +222,25 @@
         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");    
+}
 //*********************************************************************************************************************
 //* Subscribe callback (used with alternate demo)
 //*********************************************************************************************************************
@@ -281,137 +273,15 @@
     }
 }
 
-//=====================================================================================================================
-//
-// 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];
-    const string colorStrings[] = {"Off", "Red", "Green", "", "Blue", "", "", "White"};
-    float updateInterval = 1.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;
-    }
-
-    // Comment this in if you want to subscribe
-    /*MQTTSubscribeParams subParams = MQTTSubscribeParamsDefault;
-    subParams.mHandler = MQTTcallbackHandler;
-    subParams.pTopic = "sdkTest/sub";
-    subParams.qos = QOS_0;
-
-    if (NONE_ERROR == rc) {
-        INFO("Subscribing...");
-        rc = aws_iot_mqtt_subscribe(&subParams);
-        if (NONE_ERROR != rc) {
-            ERROR("Error subscribing");
-        }
-    }*/
-
-    // Initializ 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;
-    }
-      
-    INFO("READY TO PUBLISH! Press SW3 button to publish current data.");
-    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;
-        }
-        
-        // Whenever the software button (SW3) is pressed the LED will changes color and this will
-        // trigger a publish to the AWS topic specified.
-        if (buttonOverride) {
-            buttonOverride = false;
-            
-            // Get temp/humidity values
-            temperature = CTOF(hts221.readTemperature());
-            humidity = hts221.readHumidity();
-    
-            // Loading data into JSON format
-            sprintf(cPayload, "{\"color\":\"%s\",\"temperature\":%f,\"humidity\":%d}", colorStrings[ledColor], temperature, humidity);
-            Msg.PayloadLen = strlen(cPayload) + 1;
-            Params.MessageParams = Msg;
-            
-            // Publish
-            rc = aws_iot_mqtt_publish(&Params);
-            if (publishCount > 0) {
-                publishCount--;
-            }
-                      
-            printData();
-            INFO("--> Update sent. Sleep for %f seconds", updateInterval);
-            wait(updateInterval-.02);
-        }
-        else {
-            wait(.3); // 300 ms
-        }
-    }
-
-    if (NONE_ERROR != rc) {
-        ERROR("An error occurred in the loop.\n");
-    } else {
-        INFO("Publish done\n");
-    }
-
-    return rc;
+//*********************************************************************************************************************
+//* Send LCD message over bluetooth interface
+//*********************************************************************************************************************
+void setLCDMessage(string str) {
+    bluetooth.putc('*');
+    for(int i = 0; i < str.length(); i++) {
+        bluetooth.putc(str.at(i));    
+    }    
+    bluetooth.putc('\n');
 }
 
 //=====================================================================================================================
@@ -420,12 +290,11 @@
 //
 //=====================================================================================================================
 int main() {
-    
     // Set baud rate for PC Serial
     pc.baud(115200);
-    INFO("Hello World from AT&T IoT Start Kit demo!");
-              
-    int i;          
+    bluetooth.baud(9600);
+    INFO("Program Start");
+               
     IoT_Error_t rc = NONE_ERROR;  
     char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
     size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);
@@ -436,7 +305,14 @@
     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;
@@ -448,20 +324,26 @@
     humidityHandler.cb = NULL;
     humidityHandler.pKey = "humidity";
     humidityHandler.pData = &humidity;
-    humidityHandler.type = SHADOW_JSON_INT16;
+    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 
+    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);
 
-#ifdef USING_SD_CARD
-    // Paths for certs from SD card
-    INFO("Using SD card files for AWS config.");  
-    DEBUG("- mqtt config path: %s", AWS_MQTT_CONFIG_FILENAME);
-    DEBUG("- rootCA path: %s", AWS_IOT_ROOT_CA_FILENAME);
-    DEBUG("- clientCRT path: %s", AWS_IOT_CERTIFICATE_FILENAME);
-    DEBUG("- clientKey path: %s", AWS_IOT_PRIVATE_KEY_FILENAME);
-#else
+
     INFO("Using #defines in aws_iot_config.h and certs from certs.cpp for AWS config.");      
-#endif
     
     // Startup signal - blinks through RGBW then turns off
     SetLedColor(COLOR_RED);
@@ -473,30 +355,11 @@
     SetLedColor(COLOR_WHITE);
     wait(.5);
     SetLedColor(COLOR_OFF);
-    
-    // Initialize sensors
-    INFO("Init sensors...");
-    void hts221_init(void);
-    i = hts221.begin();  
-    if(!i) {
-        WARN(RED "HTS221 NOT DETECTED!!\n\r");
-    }
-      
-    // Setup SW3 button to falling edge interrupt
-    INFO("Init interrupts...");
-    Interrupt.fall(&sw3ButtonHandler);
       
     // Boot the Avnet Shield before any other operations
     INFO("Net Boot...");
     net_modem_boot();
-    
-    //==========================================================================
-    // NOTE:  You can comment in the following line for an alternate demo that
-    // is used as the out-of-box demo binary that comes with the  AT&T IoT 
-    // Starter Kit.  It loops instead of the rest of Main()
-    //return outOfBoxDemo();
-    //==========================================================================
-          
+       
     // Intialize MQTT/Cert parameters
     ShadowParameters_t sp = ShadowParametersDefault;
 #ifdef USING_SD_CARD
@@ -518,11 +381,11 @@
     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) {
@@ -540,26 +403,33 @@
     // 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;
     }
-    
-    // Example line of how to delete a shadow (not used in this demo)
-    //aws_iot_shadow_delete(&mqttClient, AWS_IOT_MY_THING_NAME, ShadowUpdateStatusCallback, NULL, 8, true);
-
+        
     INFO("Shadow Register Delta...");
     rc = aws_iot_shadow_register_delta(&mqttClient, &ledController);
     if (NONE_ERROR != rc) {
-        ERROR("Shadow Register Delta Error");
+        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");
+        return rc;
+    }
+
     INFO("Will attempt to sync with device shadow every %f seconds.", SHADOW_SYNC_INTERVAL);
     // Loop and publish changes from the FRDM board
     while (NETWORK_ATTEMPTING_RECONNECT == rc || RECONNECT_SUCCESSFUL == rc || NONE_ERROR == rc) {
-        
         // Looks for incoming socket messages
         rc = aws_iot_shadow_yield(&mqttClient, 200);
         if (NETWORK_ATTEMPTING_RECONNECT == rc) {
@@ -568,26 +438,42 @@
             wait(1);
             continue;
         }
+        //Read signal quality
+        signalQuality = WNCInterface::_pwnc->getDbmRssi();
         
         // Read sensor data
-        temperature = CTOF(hts221.readTemperature());
-        humidity = hts221.readHumidity();
-                                
+        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          
         rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
         if (rc == NONE_ERROR) {
             
-            // If there has been a SW3 button press update the 'desired' color
-            if (buttonOverride) {
-                rc = aws_iot_shadow_add_desired(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 1, &ledController);               
-                buttonOverride = false;
-            }
-                  
             // Updates the 'reported' color/temp/humidity
-            rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 3, &ledController,
-                                                                                              &temperatureHandler,
-                                                                                              &humidityHandler);
+            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);   
@@ -595,17 +481,31 @@
                 if (rc == NONE_ERROR) {
                     INFO("Update Shadow: %s", JsonDocumentBuffer);
                     rc = aws_iot_shadow_update(&mqttClient, sp.pMyThingName, JsonDocumentBuffer,
-                            ShadowUpdateStatusCallback, NULL, 8, 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);
         wait(SHADOW_SYNC_INTERVAL);
     }