Example for connecting to Cayenne using an X-NUCLEO-IDW01M1 WiFi expansion board.

Dependencies:   Cayenne-MQTT-mbed NetworkSocketAPI X_NUCLEO_IDW01M1v2 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /**
00002 * Example app for using the Cayenne MQTT C++ library to send and receive example data. This example uses
00003 * the X-NUCLEO-IDW01M1 WiFi expansion board via the X_NUCLEO_IDW01M1v2 library.
00004 */
00005 
00006 #include "MQTTTimer.h"
00007 #include "CayenneMQTTClient.h"
00008 #include "MQTTNetworkIDW01M1.h"
00009 #include "SpwfInterface.h"
00010 
00011 // WiFi network info.
00012 char* ssid = "ssid";
00013 char* wifiPassword = "wifiPassword";
00014 
00015 // Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
00016 char* username = "MQTT_USERNAME";
00017 char* password = "MQTT_PASSWORD";
00018 char* clientID = "CLIENT_ID";
00019 
00020 SpwfSAInterface interface(D8, D2); // TX, RX
00021 MQTTNetwork<SpwfSAInterface> network(interface);
00022 CayenneMQTT::MQTTClient<MQTTNetwork<SpwfSAInterface>, MQTTTimer> mqttClient(network, username, password, clientID);
00023 
00024 DigitalOut led1(LED1);
00025 
00026 /**
00027 * Print the message info.
00028 * @param[in] message The message received from the Cayenne server.
00029 */
00030 void outputMessage(CayenneMQTT::MessageData& message)
00031 {
00032     switch (message.topic)  {
00033     case COMMAND_TOPIC:
00034         printf("topic=Command");
00035         break;
00036     case CONFIG_TOPIC:
00037         printf("topic=Config");
00038         break;
00039     default:
00040         printf("topic=%d", message.topic);
00041         break;
00042     }
00043     printf(" channel=%d", message.channel);
00044     if (message.clientID) {
00045         printf(" clientID=%s", message.clientID);
00046     }
00047     if (message.type) {
00048         printf(" type=%s", message.type);
00049     }
00050     for (size_t i = 0; i < message.valueCount; ++i) {
00051         if (message.getValue(i)) {
00052             printf(" value=%s", message.getValue(i));
00053         }
00054         if (message.getUnit(i)) {
00055             printf(" unit=%s", message.getUnit(i));
00056         }
00057     }
00058     if (message.id) {
00059         printf(" id=%s", message.id);
00060     }
00061     printf("\n");
00062 }
00063 
00064 /**
00065 * Handle messages received from the Cayenne server.
00066 * @param[in] message The message received from the Cayenne server.
00067 */
00068 void messageArrived(CayenneMQTT::MessageData& message)
00069 {
00070     int error = 0;
00071     // Add code to process the message. Here we just ouput the message data.
00072     outputMessage(message);
00073 
00074     if (message.topic == COMMAND_TOPIC) {
00075         switch(message.channel) {
00076         case 0:
00077             // Set the onboard LED state
00078             led1 = atoi(message.getValue());
00079             // Publish the updated LED state
00080             if ((error = mqttClient.publishData(DATA_TOPIC, message.channel, NULL, NULL, message.getValue())) != CAYENNE_SUCCESS) {
00081                 printf("Publish LED state failure, error: %d\n", error);
00082             }
00083             break;
00084         }
00085         
00086         // If this is a command message we publish a response. Here we are just sending a default 'OK' response.
00087         // An error response should be sent if there are issues processing the message.
00088         if ((error = mqttClient.publishResponse(message.id, NULL, message.clientID)) != CAYENNE_SUCCESS) {
00089             printf("Response failure, error: %d\n", error);
00090         }
00091     }
00092 }
00093 
00094 /**
00095 * Connect to the Cayenne server.
00096 * @return Returns CAYENNE_SUCCESS if the connection succeeds, or an error code otherwise.
00097 */
00098 int connectClient(void)
00099 {
00100     int error = 0;
00101     // Connect to the server.
00102     printf("Connecting to %s:%d\n", CAYENNE_DOMAIN, CAYENNE_PORT);
00103     while ((error = network.connect(CAYENNE_DOMAIN, CAYENNE_PORT)) != 0) {
00104         printf("TCP connect failed, error: %d\n", error);
00105         wait(2);
00106     }
00107 
00108     if ((error = mqttClient.connect()) != MQTT::SUCCESS) {
00109         printf("MQTT connect failed, error: %d\n", error);
00110         return error;
00111     }
00112     printf("Connected\n");
00113 
00114     // Subscribe to required topics.
00115     if ((error = mqttClient.subscribe(COMMAND_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
00116         printf("Subscription to Command topic failed, error: %d\n", error);
00117     }
00118     if ((error = mqttClient.subscribe(CONFIG_TOPIC, CAYENNE_ALL_CHANNELS)) != CAYENNE_SUCCESS) {
00119         printf("Subscription to Config topic failed, error:%d\n", error);
00120     }
00121 
00122     // Send device info. Here we just send some example values for the system info. These should be changed to use actual system data, or removed if not needed.
00123     mqttClient.publishData(SYS_VERSION_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, CAYENNE_VERSION);
00124     mqttClient.publishData(SYS_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "mbedDevice");
00125     //mqttClient.publishData(SYS_CPU_MODEL_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "CPU Model");
00126     //mqttClient.publishData(SYS_CPU_SPEED_TOPIC, CAYENNE_NO_CHANNEL, NULL, NULL, "1000000000");
00127 
00128     return CAYENNE_SUCCESS;
00129 }
00130 
00131 /**
00132 * Main loop where MQTT code is run.
00133 */
00134 void loop(void)
00135 {
00136     // Start the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
00137     MQTTTimer timer(5000);
00138 
00139     while (true) {
00140         // Yield to allow MQTT message processing.
00141         mqttClient.yield(1000);
00142 
00143         // Check that we are still connected, if not, reconnect.
00144         if (!network.connected() || !mqttClient.connected()) {
00145             network.disconnect();
00146             mqttClient.disconnect();
00147             printf("Reconnecting\n");
00148             while (connectClient() != CAYENNE_SUCCESS) {
00149                 wait(2);
00150                 printf("Reconnect failed, retrying\n");
00151             }
00152         }
00153 
00154         // Publish some example data every few seconds. This should be changed to send your actual data to Cayenne.
00155         if (timer.expired()) {
00156             int error = 0;
00157             if ((error = mqttClient.publishData(DATA_TOPIC, 1, TYPE_TEMPERATURE, UNIT_CELSIUS, 30.5)) != CAYENNE_SUCCESS) {
00158                 printf("Publish temperature failed, error: %d\n", error);
00159             }
00160             if ((error = mqttClient.publishData(DATA_TOPIC, 2, TYPE_LUMINOSITY, UNIT_LUX, 1000)) != CAYENNE_SUCCESS) {
00161                 printf("Publish luminosity failed, error: %d\n", error);
00162             }
00163             if ((error = mqttClient.publishData(DATA_TOPIC, 3, TYPE_BAROMETRIC_PRESSURE, UNIT_HECTOPASCAL, 800)) != CAYENNE_SUCCESS) {
00164                 printf("Publish barometric pressure failed, error: %d\n", error);
00165             }
00166             // Restart the countdown timer for publishing data every 5 seconds. Change the timeout parameter to publish at a different interval.
00167             timer.countdown_ms(5000);
00168         }
00169     }
00170 }
00171 
00172 /**
00173 * Main function.
00174 */
00175 int main()
00176 {   
00177     // Initialize the network interface.
00178     printf("Initializing interface\n");
00179     interface.connect(ssid, wifiPassword, NSAPI_SECURITY_WPA2);
00180 
00181     // Set the default function that receives Cayenne messages.
00182     mqttClient.setDefaultMessageHandler(messageArrived);
00183 
00184     // Connect to Cayenne.
00185     if (connectClient() == CAYENNE_SUCCESS) {
00186         // Run main loop.
00187         loop();
00188     }
00189     else {
00190         printf("Connection failed, exiting\n");
00191     }
00192 
00193     if (mqttClient.connected())
00194         mqttClient.disconnect();
00195     if (network.connected())
00196         network.disconnect();
00197 
00198     return 0;
00199 }
00200