Changes to enabled on-line compiler

Revision:
0:082731ede69f
diff -r 000000000000 -r 082731ede69f examples/shadow_sample/shadow_sample.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/shadow_sample/shadow_sample.c	Wed May 30 20:59:51 2018 +0000
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License").
+ * You may not use this file except in compliance with the License.
+ * A copy of the License is located at
+ *
+ *  http://aws.amazon.com/apache2.0
+ *
+ * or in the "license" file accompanying this file. This file is distributed
+ * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+ * express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+/**
+ * @file shadow_sample.c
+ * @brief A simple connected window example demonstrating the use of Thing Shadow
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <string.h>
+#include <limits.h>
+
+#include "aws_iot_config.h"
+#include "aws_iot_log.h"
+#include "aws_iot_version.h"
+#include "aws_iot_mqtt_client_interface.h"
+#include "aws_iot_shadow_interface.h"
+
+/*!
+ * The goal of this sample application is to demonstrate the capabilities of shadow.
+ * This device(say Connected Window) will open the window of a room based on temperature
+ * It can report to the Shadow the following parameters:
+ *  1. temperature of the room (double)
+ *  2. status of the window (open or close)
+ * It can act on commands from the cloud. In this case it will open or close the window based on the json object "windowOpen" data[open/close]
+ *
+ * The two variables from a device's perspective are double temperature and bool windowOpen
+ * The device needs to act on only on windowOpen variable, so we will create a primitiveJson_t object with callback
+ The Json Document in the cloud will be
+ {
+ "reported": {
+ "temperature": 0,
+ "windowOpen": false
+ },
+ "desired": {
+ "windowOpen": false
+ }
+ }
+ */
+
+#define ROOMTEMPERATURE_UPPERLIMIT 32.0f
+#define ROOMTEMPERATURE_LOWERLIMIT 25.0f
+#define STARTING_ROOMTEMPERATURE ROOMTEMPERATURE_LOWERLIMIT
+
+#define MAX_LENGTH_OF_UPDATE_JSON_BUFFER 200
+
+static char certDirectory[PATH_MAX + 1] = "../../../certs";
+#define HOST_ADDRESS_SIZE 255
+static char HostAddress[HOST_ADDRESS_SIZE] = AWS_IOT_MQTT_HOST;
+static uint32_t port = AWS_IOT_MQTT_PORT;
+static uint8_t numPubs = 5;
+
+static void simulateRoomTemperature(float *pRoomTemperature) {
+	static float deltaChange;
+
+	if(*pRoomTemperature >= ROOMTEMPERATURE_UPPERLIMIT) {
+		deltaChange = -0.5f;
+	} else if(*pRoomTemperature <= ROOMTEMPERATURE_LOWERLIMIT) {
+		deltaChange = 0.5f;
+	}
+
+	*pRoomTemperature += deltaChange;
+}
+
+void ShadowUpdateStatusCallback(const char *pThingName, ShadowActions_t action, Shadow_Ack_Status_t status,
+								const char *pReceivedJsonDocument, void *pContextData) {
+	IOT_UNUSED(pThingName);
+	IOT_UNUSED(action);
+	IOT_UNUSED(pReceivedJsonDocument);
+	IOT_UNUSED(pContextData);
+
+	if(SHADOW_ACK_TIMEOUT == status) {
+		IOT_INFO("Update Timeout--");
+	} else if(SHADOW_ACK_REJECTED == status) {
+		IOT_INFO("Update RejectedXX");
+	} else if(SHADOW_ACK_ACCEPTED == status) {
+		IOT_INFO("Update Accepted !!");
+	}
+}
+
+void windowActuate_Callback(const char *pJsonString, uint32_t JsonStringDataLen, jsonStruct_t *pContext) {
+	IOT_UNUSED(pJsonString);
+	IOT_UNUSED(JsonStringDataLen);
+
+	if(pContext != NULL) {
+		IOT_INFO("Delta - Window state changed to %d", *(bool *) (pContext->pData));
+	}
+}
+
+void parseInputArgsForConnectParams(int argc, char **argv) {
+	int opt;
+
+	while(-1 != (opt = getopt(argc, argv, "h:p:c:n:"))) {
+		switch(opt) {
+			case 'h':
+				strncpy(HostAddress, optarg, HOST_ADDRESS_SIZE);
+				IOT_DEBUG("Host %s", optarg);
+				break;
+			case 'p':
+				port = atoi(optarg);
+				IOT_DEBUG("arg %s", optarg);
+				break;
+			case 'c':
+				strncpy(certDirectory, optarg, PATH_MAX + 1);
+				IOT_DEBUG("cert root directory %s", optarg);
+				break;
+			case 'n':
+				numPubs = atoi(optarg);
+				IOT_DEBUG("num pubs %s", optarg);
+				break;
+			case '?':
+				if(optopt == 'c') {
+					IOT_ERROR("Option -%c requires an argument.", optopt);
+				} else if(isprint(optopt)) {
+					IOT_WARN("Unknown option `-%c'.", optopt);
+				} else {
+					IOT_WARN("Unknown option character `\\x%x'.", optopt);
+				}
+				break;
+			default:
+				IOT_ERROR("ERROR in command line argument parsing");
+				break;
+		}
+	}
+
+}
+
+int main(int argc, char **argv) {
+	IoT_Error_t rc = FAILURE;
+	int32_t i = 0;
+
+	char JsonDocumentBuffer[MAX_LENGTH_OF_UPDATE_JSON_BUFFER];
+	size_t sizeOfJsonDocumentBuffer = sizeof(JsonDocumentBuffer) / sizeof(JsonDocumentBuffer[0]);
+	char *pJsonStringToUpdate;
+	float temperature = 0.0;
+
+	bool windowOpen = false;
+	jsonStruct_t windowActuator;
+	windowActuator.cb = windowActuate_Callback;
+	windowActuator.pData = &windowOpen;
+	windowActuator.dataLength = sizeof(bool);
+	windowActuator.pKey = "windowOpen";
+	windowActuator.type = SHADOW_JSON_BOOL;
+
+	jsonStruct_t temperatureHandler;
+	temperatureHandler.cb = NULL;
+	temperatureHandler.pKey = "temperature";
+	temperatureHandler.pData = &temperature;
+	temperatureHandler.dataLength = sizeof(float);
+	temperatureHandler.type = SHADOW_JSON_FLOAT;
+
+	char rootCA[PATH_MAX + 1];
+	char clientCRT[PATH_MAX + 1];
+	char clientKey[PATH_MAX + 1];
+	char CurrentWD[PATH_MAX + 1];
+
+	IOT_INFO("\nAWS IoT SDK Version %d.%d.%d-%s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_TAG);
+
+	getcwd(CurrentWD, sizeof(CurrentWD));
+	snprintf(rootCA, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_ROOT_CA_FILENAME);
+	snprintf(clientCRT, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_CERTIFICATE_FILENAME);
+	snprintf(clientKey, PATH_MAX + 1, "%s/%s/%s", CurrentWD, certDirectory, AWS_IOT_PRIVATE_KEY_FILENAME);
+
+	IOT_DEBUG("rootCA %s", rootCA);
+	IOT_DEBUG("clientCRT %s", clientCRT);
+	IOT_DEBUG("clientKey %s", clientKey);
+
+	parseInputArgsForConnectParams(argc, argv);
+
+	// initialize the mqtt client
+	AWS_IoT_Client mqttClient;
+
+	ShadowInitParameters_t sp = ShadowInitParametersDefault;
+	sp.pHost = AWS_IOT_MQTT_HOST;
+	sp.port = AWS_IOT_MQTT_PORT;
+	sp.pClientCRT = clientCRT;
+	sp.pClientKey = clientKey;
+	sp.pRootCA = rootCA;
+	sp.enableAutoReconnect = false;
+	sp.disconnectHandler = NULL;
+
+	IOT_INFO("Shadow Init");
+	rc = aws_iot_shadow_init(&mqttClient, &sp);
+	if(SUCCESS != rc) {
+		IOT_ERROR("Shadow Connection Error");
+		return rc;
+	}
+
+	ShadowConnectParameters_t scp = ShadowConnectParametersDefault;
+	scp.pMyThingName = AWS_IOT_MY_THING_NAME;
+	scp.pMqttClientId = AWS_IOT_MQTT_CLIENT_ID;
+	scp.mqttClientIdLen = (uint16_t) strlen(AWS_IOT_MQTT_CLIENT_ID);
+
+	IOT_INFO("Shadow Connect");
+	rc = aws_iot_shadow_connect(&mqttClient, &scp);
+	if(SUCCESS != rc) {
+		IOT_ERROR("Shadow Connection Error");
+		return rc;
+	}
+
+	/*
+	 * 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 = aws_iot_shadow_set_autoreconnect_status(&mqttClient, true);
+	if(SUCCESS != rc) {
+		IOT_ERROR("Unable to set Auto Reconnect to true - %d", rc);
+		return rc;
+	}
+
+	rc = aws_iot_shadow_register_delta(&mqttClient, &windowActuator);
+
+	if(SUCCESS != rc) {
+		IOT_ERROR("Shadow Register Delta Error");
+	}
+	temperature = STARTING_ROOMTEMPERATURE;
+
+	// loop and publish a change in temperature
+	while(NETWORK_ATTEMPTING_RECONNECT == rc || NETWORK_RECONNECTED == rc || SUCCESS == rc) {
+		rc = aws_iot_shadow_yield(&mqttClient, 200);
+		if(NETWORK_ATTEMPTING_RECONNECT == rc) {
+			sleep(1);
+			// If the client is attempting to reconnect we will skip the rest of the loop.
+			continue;
+		}
+		IOT_INFO("\n=======================================================================================\n");
+		IOT_INFO("On Device: window state %s", windowOpen ? "true" : "false");
+		simulateRoomTemperature(&temperature);
+
+		rc = aws_iot_shadow_init_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
+		if(SUCCESS == rc) {
+			rc = aws_iot_shadow_add_reported(JsonDocumentBuffer, sizeOfJsonDocumentBuffer, 2, &temperatureHandler,
+											 &windowActuator);
+			if(SUCCESS == rc) {
+				rc = aws_iot_finalize_json_document(JsonDocumentBuffer, sizeOfJsonDocumentBuffer);
+				if(SUCCESS == rc) {
+					IOT_INFO("Update Shadow: %s", JsonDocumentBuffer);
+					rc = aws_iot_shadow_update(&mqttClient, AWS_IOT_MY_THING_NAME, JsonDocumentBuffer,
+											   ShadowUpdateStatusCallback, NULL, 4, true);
+				}
+			}
+		}
+		IOT_INFO("*****************************************************************************************\n");
+		sleep(1);
+	}
+
+	if(SUCCESS != rc) {
+		IOT_ERROR("An error occurred in the loop %d", rc);
+	}
+
+	IOT_INFO("Disconnecting");
+	rc = aws_iot_shadow_disconnect(&mqttClient);
+
+	if(SUCCESS != rc) {
+		IOT_ERROR("Disconnect error %d", rc);
+	}
+
+	return rc;
+}