This example program uses the ARM mbed HTTP client library to send/receive data to/from AT&T's M2X service (https://m2x.att.com/) using the AT&T Cellular IoT Starter Kit from Avnet (http://cloudconnectkits.org/product/att-cellular-iot-starter-kit). This kit contains a FRDM-K64F from NXP (https://developer.mbed.org/platforms/FRDM-K64F/).
Dependencies: M2XStreamClient-JMF WNCInterface jsonlite mbed-rtos mbed
See the README for details on this example program. NOTE: When started, the program can take up to 40 seconds before it will respond. This delay is the time required for the WNC Data Module to connect with the network.
main.cpp@3:94a2e1a54aac, 2016-11-17 (annotated)
- Committer:
- root@developer-sjc-cyan-compiler.local.mbed.org
- Date:
- Thu Nov 17 18:40:25 2016 +0000
- Revision:
- 3:94a2e1a54aac
- Parent:
- 2:eb0768c06c1b
Added tag att_cellular_K64_wnc_14A2A_20161117 for changeset eb0768c06c1b
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
JMF | 0:62feed0f1fd9 | 1 | // |
JMF | 0:62feed0f1fd9 | 2 | // This file contains an example implementation of M2X using the HTTP interface as the underlying |
JMF | 0:62feed0f1fd9 | 3 | // transport. |
JMF | 0:62feed0f1fd9 | 4 | // |
JMF | 0:62feed0f1fd9 | 5 | |
JMF | 0:62feed0f1fd9 | 6 | #include "mbed.h" |
JMF | 0:62feed0f1fd9 | 7 | #include "WNCInterface.h" |
JMF | 0:62feed0f1fd9 | 8 | |
JMF | 0:62feed0f1fd9 | 9 | #define MBED_PLATFORM |
JMF | 0:62feed0f1fd9 | 10 | #define M2X_ENABLE_READER |
JMF | 0:62feed0f1fd9 | 11 | |
JMF | 0:62feed0f1fd9 | 12 | #include <jsonlite.h> |
JMF | 0:62feed0f1fd9 | 13 | #include "M2XStreamClient.h" |
JMF | 0:62feed0f1fd9 | 14 | |
JMF | 0:62feed0f1fd9 | 15 | #define CRLF "\n\r" |
JMF | 0:62feed0f1fd9 | 16 | |
JMF | 0:62feed0f1fd9 | 17 | char deviceId[] = "e83cdd8645ab1a7c0c480156efbf78f6"; // Device you want to post to |
JMF | 0:62feed0f1fd9 | 18 | char m2xKey[] = "4d7e1da7f05c3fa4d5426419891a254d"; // Your M2X API Key or Master API Key |
JMF | 0:62feed0f1fd9 | 19 | |
JMF | 0:62feed0f1fd9 | 20 | const char *hstreamName = "humidity"; |
JMF | 0:62feed0f1fd9 | 21 | const char *tstreamName = "temperature"; |
JMF | 0:62feed0f1fd9 | 22 | const char *streamNames[] = { tstreamName, hstreamName }; |
JMF | 0:62feed0f1fd9 | 23 | char name[] = "Wake Forest"; // Name of current location of datasource |
JMF | 0:62feed0f1fd9 | 24 | |
JMF | 0:62feed0f1fd9 | 25 | int counts[] = { 2, 1 }; |
JMF | 0:62feed0f1fd9 | 26 | const char *ats[] = { "2016-09-09T02:05:14.692Z", |
JMF | 0:62feed0f1fd9 | 27 | "2016-09-09T02:05:14.700Z", |
JMF | 0:62feed0f1fd9 | 28 | "2016-09-09T02:05:14.692Z" }; |
JMF | 0:62feed0f1fd9 | 29 | double values[] = { 10.9, 11.2, 6.1 }; |
JMF | 0:62feed0f1fd9 | 30 | |
JMF | 0:62feed0f1fd9 | 31 | char fromTime[]= "1969-12-31T19:00:01.000Z"; // yyyy-mm-ddTHH:MM:SS.SSSZ |
JMF | 0:62feed0f1fd9 | 32 | char endTime[25]; |
JMF | 0:62feed0f1fd9 | 33 | |
JMF | 0:62feed0f1fd9 | 34 | double latitude = 33.007872; // You could read these values from a GPS but |
JMF | 0:62feed0f1fd9 | 35 | double longitude = -96.751614; // for now, will just hardcode them |
JMF | 0:62feed0f1fd9 | 36 | double elevation = 697.00; |
JMF | 0:62feed0f1fd9 | 37 | |
JMF | 0:62feed0f1fd9 | 38 | WNCInterface eth; |
JMF | 0:62feed0f1fd9 | 39 | Client client; |
JMF | 0:62feed0f1fd9 | 40 | M2XStreamClient m2xClient(&client, m2xKey); |
JMF | 0:62feed0f1fd9 | 41 | TimeService timeService(&m2xClient); |
JMF | 1:1c840717deea | 42 | MODSERIAL pc(USBTX,USBRX,256,256); |
JMF | 0:62feed0f1fd9 | 43 | |
JMF | 0:62feed0f1fd9 | 44 | void on_data_point_found(const char* at, const char* value, int index, void* context, int type) { |
JMF | 2:eb0768c06c1b | 45 | pc.printf(">>Found a data point, index: %d type: %d" CRLF, index, type); |
JMF | 2:eb0768c06c1b | 46 | pc.printf(">>At: %s" CRLF " Value: %s" CRLF, at, value); |
JMF | 0:62feed0f1fd9 | 47 | } |
JMF | 0:62feed0f1fd9 | 48 | |
JMF | 0:62feed0f1fd9 | 49 | |
JMF | 0:62feed0f1fd9 | 50 | void on_command_found(const char* id, const char* name, int index, void *context) { |
JMF | 2:eb0768c06c1b | 51 | pc.printf(">>Found a command, index: %d" CRLF, index); |
JMF | 2:eb0768c06c1b | 52 | pc.printf(">>ID: %s\n Name: %s" CRLF, id, name); |
JMF | 0:62feed0f1fd9 | 53 | } |
JMF | 0:62feed0f1fd9 | 54 | |
JMF | 0:62feed0f1fd9 | 55 | void on_location_found(const char* name, |
JMF | 0:62feed0f1fd9 | 56 | double latitude, |
JMF | 0:62feed0f1fd9 | 57 | double longitude, |
JMF | 0:62feed0f1fd9 | 58 | double elevation, |
JMF | 0:62feed0f1fd9 | 59 | const char* timestamp, |
JMF | 0:62feed0f1fd9 | 60 | int index, |
JMF | 0:62feed0f1fd9 | 61 | void* context) { |
JMF | 2:eb0768c06c1b | 62 | pc.printf(">>Found a location, index: %d" CRLF, index); |
JMF | 2:eb0768c06c1b | 63 | pc.printf(">>Name: %s" CRLF ">>Latitude: %lf" CRLF ">>Longitude: %lf" CRLF, name, latitude, longitude); |
JMF | 2:eb0768c06c1b | 64 | pc.printf(">>Elevation: %lf" CRLF ">>Timestamp: %s" CRLF, elevation, timestamp); |
JMF | 0:62feed0f1fd9 | 65 | } |
JMF | 0:62feed0f1fd9 | 66 | |
JMF | 0:62feed0f1fd9 | 67 | int main() { |
JMF | 0:62feed0f1fd9 | 68 | char timestamp[25]; |
JMF | 0:62feed0f1fd9 | 69 | int length = 25; |
JMF | 0:62feed0f1fd9 | 70 | char amb_temp[6]; |
JMF | 0:62feed0f1fd9 | 71 | char amb_humd[6]; |
JMF | 0:62feed0f1fd9 | 72 | int response, cnt=1; |
JMF | 0:62feed0f1fd9 | 73 | double temp=0.00; //we will just increment these 0.01 each time through the loop |
JMF | 0:62feed0f1fd9 | 74 | double humid=0.00; //we will just increment these 1 each time through the loop wrapping at 100 |
JMF | 0:62feed0f1fd9 | 75 | |
JMF | 1:1c840717deea | 76 | pc.baud(115200); |
JMF | 2:eb0768c06c1b | 77 | pc.printf("Start m2x-demo-all by initializng the network" CRLF); |
JMF | 0:62feed0f1fd9 | 78 | response = eth.init(); |
JMF | 2:eb0768c06c1b | 79 | pc.printf("WNC Module %s initialized (%02X)." CRLF, response?"IS":"IS NOT", response); |
JMF | 0:62feed0f1fd9 | 80 | if( !response ) { |
JMF | 2:eb0768c06c1b | 81 | pc.printf(" - - - - - - - ALL DONE - - - - - - - " CRLF); |
JMF | 0:62feed0f1fd9 | 82 | while(1); |
JMF | 0:62feed0f1fd9 | 83 | } |
JMF | 0:62feed0f1fd9 | 84 | |
JMF | 2:eb0768c06c1b | 85 | response = eth.connect(); |
JMF | 2:eb0768c06c1b | 86 | pc.printf("IP Address: %s " CRLF CRLF, eth.getIPAddress()); |
JMF | 0:62feed0f1fd9 | 87 | |
JMF | 2:eb0768c06c1b | 88 | pc.printf("initialize the M2X time service" CRLF); |
JMF | 0:62feed0f1fd9 | 89 | if (!m2x_status_is_success(timeService.init())) |
JMF | 2:eb0768c06c1b | 90 | pc.printf("Cannot initialize time service!" CRLF); |
JMF | 0:62feed0f1fd9 | 91 | else { |
JMF | 2:eb0768c06c1b | 92 | timeService.getTimestamp(timestamp, &length); |
JMF | 2:eb0768c06c1b | 93 | pc.printf("Current timestamp: %s" CRLF, timestamp); |
JMF | 2:eb0768c06c1b | 94 | strcpy(endTime,timestamp); |
JMF | 0:62feed0f1fd9 | 95 | } |
JMF | 0:62feed0f1fd9 | 96 | |
JMF | 2:eb0768c06c1b | 97 | pc.printf("Now delete all existing values" CRLF); |
JMF | 0:62feed0f1fd9 | 98 | // Delete values |
JMF | 2:eb0768c06c1b | 99 | pc.printf("Delete humidity values..." CRLF); |
JMF | 0:62feed0f1fd9 | 100 | response = m2xClient.deleteValues(deviceId,hstreamName, fromTime, endTime); |
JMF | 2:eb0768c06c1b | 101 | pc.printf("Delete response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 102 | |
JMF | 2:eb0768c06c1b | 103 | pc.printf("Delete temp values..." CRLF); |
JMF | 0:62feed0f1fd9 | 104 | response = m2xClient.deleteValues(deviceId,tstreamName, fromTime, endTime); |
JMF | 2:eb0768c06c1b | 105 | pc.printf("Delete response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 106 | |
JMF | 2:eb0768c06c1b | 107 | pc.printf("Delete location values..." CRLF); |
JMF | 0:62feed0f1fd9 | 108 | response = m2xClient.deleteLocations(deviceId, fromTime, endTime); |
JMF | 2:eb0768c06c1b | 109 | pc.printf("Delete response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 110 | |
JMF | 2:eb0768c06c1b | 111 | pc.printf("Query for possible commands using this device..." CRLF); |
JMF | 0:62feed0f1fd9 | 112 | response = m2xClient.listCommands(deviceId, on_command_found, NULL); |
JMF | 2:eb0768c06c1b | 113 | pc.printf("listCommands response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 114 | |
JMF | 0:62feed0f1fd9 | 115 | while (true) { |
JMF | 0:62feed0f1fd9 | 116 | // read temp -- for now, just use a fixed temp, but will need to read the HTS221 |
JMF | 0:62feed0f1fd9 | 117 | // and put it into a 6 byte string formatted as "%0.2f" |
JMF | 0:62feed0f1fd9 | 118 | sprintf(amb_temp,"%0.2f",temp); |
JMF | 0:62feed0f1fd9 | 119 | sprintf(amb_humd,"%0.2f",humid); |
JMF | 0:62feed0f1fd9 | 120 | temp += .01; |
JMF | 0:62feed0f1fd9 | 121 | humid += 1.0; |
JMF | 0:62feed0f1fd9 | 122 | humid = fmod(humid,100.0); |
JMF | 2:eb0768c06c1b | 123 | pc.printf("cnt=%d\r\n",cnt++); |
JMF | 0:62feed0f1fd9 | 124 | // post the humidity value |
JMF | 2:eb0768c06c1b | 125 | pc.printf("Post updateStreamValue (humidity)..." CRLF); |
JMF | 0:62feed0f1fd9 | 126 | response = m2xClient.updateStreamValue(deviceId, "humidity", humid); |
JMF | 2:eb0768c06c1b | 127 | pc.printf("Post response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 128 | |
JMF | 0:62feed0f1fd9 | 129 | // post the temp value |
JMF | 2:eb0768c06c1b | 130 | pc.printf("Post updateStreamValue (temp)..." CRLF); |
JMF | 0:62feed0f1fd9 | 131 | response = m2xClient.updateStreamValue(deviceId, "temperature", temp); |
JMF | 2:eb0768c06c1b | 132 | pc.printf("Post response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 133 | |
JMF | 0:62feed0f1fd9 | 134 | // read temperature |
JMF | 2:eb0768c06c1b | 135 | pc.printf("listStreamValues (temp)..." CRLF); |
JMF | 0:62feed0f1fd9 | 136 | response = m2xClient.listStreamValues(deviceId, tstreamName, on_data_point_found, NULL); |
JMF | 2:eb0768c06c1b | 137 | pc.printf("listStreamValues response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 138 | if (response == -1) while (true) ; |
JMF | 0:62feed0f1fd9 | 139 | |
JMF | 0:62feed0f1fd9 | 140 | // read temperature |
JMF | 2:eb0768c06c1b | 141 | pc.printf("listStreamValues (humid)..." CRLF); |
JMF | 0:62feed0f1fd9 | 142 | response = m2xClient.listStreamValues(deviceId, hstreamName, on_data_point_found, NULL); |
JMF | 2:eb0768c06c1b | 143 | pc.printf("listStreamValues response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 144 | if (response == -1) while (true) ; |
JMF | 0:62feed0f1fd9 | 145 | |
JMF | 0:62feed0f1fd9 | 146 | // update location |
JMF | 2:eb0768c06c1b | 147 | pc.printf("updateLocation..." CRLF); |
JMF | 0:62feed0f1fd9 | 148 | response = m2xClient.updateLocation(deviceId, name, latitude, longitude, elevation); |
JMF | 2:eb0768c06c1b | 149 | pc.printf("updateLocation response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 150 | if (response == -1) while (true) ; |
JMF | 0:62feed0f1fd9 | 151 | |
JMF | 0:62feed0f1fd9 | 152 | // read location |
JMF | 2:eb0768c06c1b | 153 | pc.printf("readLocation..." CRLF); |
JMF | 0:62feed0f1fd9 | 154 | int response = m2xClient.readLocation(deviceId, on_location_found, NULL); |
JMF | 2:eb0768c06c1b | 155 | pc.printf("readLocation response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 156 | |
JMF | 2:eb0768c06c1b | 157 | pc.printf("PostDeviceUpdates..." CRLF); |
JMF | 0:62feed0f1fd9 | 158 | response = m2xClient.postDeviceUpdates(deviceId, 2, streamNames, counts, ats, values); |
JMF | 2:eb0768c06c1b | 159 | pc.printf("Post response code: %d" CRLF, response); |
JMF | 0:62feed0f1fd9 | 160 | |
JMF | 0:62feed0f1fd9 | 161 | timeService.getTimestamp(timestamp, &length); |
JMF | 2:eb0768c06c1b | 162 | pc.printf("Thats all folks, got to wait 60 seconds... (%s)" CRLF CRLF CRLF, timestamp); |
JMF | 0:62feed0f1fd9 | 163 | |
JMF | 0:62feed0f1fd9 | 164 | // wait 60 secs and then loop |
JMF | 0:62feed0f1fd9 | 165 | delay(6000); |
JMF | 0:62feed0f1fd9 | 166 | |
JMF | 0:62feed0f1fd9 | 167 | |
JMF | 0:62feed0f1fd9 | 168 | } |
JMF | 0:62feed0f1fd9 | 169 | } |
JMF | 0:62feed0f1fd9 | 170 |