Example for connecting to Cayenne using the WIZ820ioInterface (W5200) library.

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