ARM mbed M2X API Client
NOTE: We've changed one API function to avoid ambiguity. If you are using the older version of this library, there's a chance that you need to update your existing code to reflect the changed API.
- Signup for an M2X Account.
- Obtain your Master Key from the Master Keys tab of your Account Settings screen.
- Create your first Device and copy its Device ID.
- Review the M2X API Documentation.
- You have 2 choices for hardware: you can obtain an mbed LPC1768 with an mbed application board, or you can obtain a FRDM-K64F board.
NOTE: Though similiar boards exist and may also do the job, this doc is specific to using a combination of mbed LPC1768 microcontroller and mbed application board, or a single FRDM-K64F
ublox Modem/GPS shield users can find a m2x working demo with freescale boards on the mbed website here.
Please consult the M2X glossary if you have questions about any M2X specific terms.
How to run the examples
To run the examples, please follow the steps below:
Launch mbed online compiler in your browser
Newto create a new program, select
Empty Programas the template and give it a name, then click
Right click on the project you just created, select
Import Library…->From Import Wizard…, select
Librariestab, use the scrollbar or the search box at the right to find
mbedlibrary, double click it to import it.
Use the same step as #3 to import
EthernetInterface(mbed official) libraries.
NOTE: To Run the
PostExampleexample, you also need to import
LM75Blibrary in the same way to use the temperature sensor.
Right click on the project, select
Import Library…->From URL…, paste the following URL into
Importto import jsonlite library.
Use the same step as #5 to import the following M2X client library:
Create a file named
main.cpp, and paste in any of the examples. Modify the M2X API Key, device ID or stream name as needed by the examples.
At the top right corner, make sure you are selecting the same platform as your board.
When you are done, click
Compile. if no error is found, a bin file will be downloaded to your computer.
Copy that bin file to your mbed microcontroller, press the
resetbutton, then you should be able to run the program!
Variables used in Examples
In order to run the given examples, different variables need to be configured. We will walk through those variables in this section.
M2X API Key
Once you register for an AT&T M2X account, an API key is automatically generated for you. This key is called a Primary Master Key and can be found in the Master Keys tab of your Account Settings. This key cannot be edited nor deleted, but it can be regenerated. It will give you full access to all APIs.
However, you can also create a Device API Key associated with a given Device, you can use the Device API key to access the streams belonging to that Device.
You can customize this variable in the following line in the examples:
char m2xKey = "<M2X access key>";
A device is associated with a source of data. It is a set of data streams, such as streams of locations, temperatures, etc. The following line is needed to configure the device used:
char deviceId = "<device id>";
A stream in a device is a set of timed series data of a specific type (i,e. humidity, temperature), you can use the M2XStreamClient library to send stream values to M2X server, or receive stream values from M2X server. Use the following line to configure the stream if needed:
char streamName = "<stream name>";
Using the M2XStreamClient library
In the M2XStreamClient, the following API functions are provided:
updateStreamValue: Send stream value to M2X server
postDeviceUpdates: Post values from multiple streams to M2X server
listStreamValues: Receive stream value from M2X server
updateLocation: Send location value of a device to M2X server
readLocation: Receive location values of a device from M2X server
deleteValues: Delete stream values from M2X server
For all those functions, the HTTP status code will be returned if we can fulfill a HTTP request. For example,
200 will be returned upon success,
401 will be returned if we didn't provide a valid M2X API Key.
Otherwise, the following error codes will be used:
static const int E_NOCONNECTION = -1; static const int E_DISCONNECTED = -2; static const int E_NOTREACHABLE = -3; static const int E_INVALID = -4; static const int E_JSON_INVALID = -5;
Update stream value
The following functions can be used to post one single value to a stream, which belongs to a device:
template <class T> int updateStreamValue(const char* deviceId, const char* streamName, T value);
Here we use C++ templates to generate functions for different types of values, feel free to use values of
long or even
const char* types here.
NOTE: Our example here is configured to use a temperature sensor for generating values, this only applies to LPC1768 board with the application extention board. If you are using FRDM-K64F board, you might need to change this code or attach a separate temperature sensor.
Post device updates
M2X also supports posting multiple values to multiple streams in one call, use the following function for this:
template <class T> int postDeviceUpdates(const char* deviceId, int streamNum, const char* names, const int counts, const char* ats, T values);
Please refer to the comments in the source code on how to use this function, basically, you need to provide the list of streams you want to post to, and values for each stream.
List stream values
Since mbed microcontroller contains very limited memory, we cannot put the whole returned string in memory, parse it into JSON representations and read what we want. Instead, we use a callback-based mechanism here. We parse the returned JSON string piece by piece, whenever we got a new stream value point, we will call the following callback functions:
typedef void (*stream_value_read_callback)(const char* at, const char* value, int index, void* context, int type);
The implementation of the callback function is left for the user to fill in, you can read the value of the point in the
value argument, and the timestamp of the point in the
at argument. We even pass the index of this this data point in the whole stream as well as a user-specified context variable to this function, so as you can perform different tasks on this.
type indicates the type of value stored in
value: 1 for string, 2 for number. However, keep in mind that
value will always be a pointer to an array of char, even though
type indicates the current value is a number. In this case,
atof might be needed.
To read the stream values, all you need to do is calling this function:
int listStreamValues(const char* deviceId, const char* streamName, stream_value_read_callback callback, void* context, const char* query = NULL);
Besides the device ID and stream name, only the callback function and a user context needs to be specified. Optional query parameters might also be available here, for example, the current query parameter picks value from a specific range:
Update Device Location
You can use the following function to update the location for a device:
template <class T> int updateLocation(const char* deviceId, const char* name, T latitude, T longitude, T elevation);
Different from stream values, locations are attached to devices rather than streams. We use templates here, since the values may be in different format, for example, you can express latitudes in both
Read Device Location
Similar to reading stream values, we also use callback functions here. The only difference is that different parameters are used in the function:
void (*location_read_callback)(const char* name, double latitude, double longitude, double elevation, const char* timestamp, int index, void* context);
For memory space consideration, now we only provide double-precision when reading locations. An index of the location points is also provided here together with a user-specified context.
The API is also slightly different, in that the stream name is not needed here:
int readLocation(const char* deviceId, location_read_callback callback, void* context);
Delete stream values
The following function can be used to delete stream values within a date range:
int deleteValues(const char* deviceId, const char* streamName, const char* from, const char* end);
end fields here follow ISO 8601 time format.
Adjust read buffer
In reader functions, by default we use a buffer of 32 bytes to store temporary response data from server. But if memory is not a concern for you, you might want to boost buffer size for better performance and avoiding potential problems with this:
#define M2X_STREAM_BUF_LEN 128
How to read Serial output
Though you can use
printf on a mbed microcontroller, the output is sent to Serial output. To check what your microcontroller outputs to serial ports, follow the instructions at here.
We provide a series of examples that will help you get an idea of how to use the
M2XStreamClient library to perform all kinds of tasks.
Note that the examples contain fictionary variables, and that they need to be configured as per the instructions above before running on your mbed microcontroller. Each of the examples here also needs an Internet connection setup, either via an Ethernet port or a Wifi module.
UpdateStreamValue example, the temperature sensor on the mbed application board is needed. For other examples, no extra modules are needed besides the network connection.
This example shows how to post temperatures to M2X server. Before running this, you need to have a valid M2X Key, a device ID and a stream name. The mbed microcontroller need to be hooked on the mbed application board in order to use the temperature sensor.
This example shows how to post multiple values to multiple streams in one API call.
This example reads stream values from M2X server. And prints the stream data point got to Serial interface. You can find the actual values in the Serial output.
This one sends location data to M2X server. Idealy a GPS device should be used here to read the cordinates, but for simplicity, we just use pre-set values here to show how to use the API.
This one reads location data of a device from M2X server, and prints them to Serial interfact. You can check the output in the Serial output.
This example shows how to delete stream values within a specific range from M2X server.
This library is released under the MIT license. See
M2XStreamClient/LICENSE for the terms.