![](/media/cache/profiles/5f55d0baa59f4bc1dc393149183f1492.jpg.50x50_q85.jpg)
Changes to enabled on-line compiler
examples/shadow_sample/shadow_sample.c
- Committer:
- JMF
- Date:
- 2018-05-30
- Revision:
- 0:082731ede69f
File content as of revision 0:082731ede69f:
/* * 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; }