Let’s say you have looked at the Getting Started with Spark.publish() tutorial, but you need to send data that needs more processing once it gets to its destination on the web. You have a lot of choices for the data format, but one simple choice is to use JSON, the JavaScript Object Notation which let you send property names and values in an easy to read and easy parse to format.
You may have noticed in fact that the data returned by listening to the event stream from a published event is already itself a JSON with fields like “coreid” and “TTL” for time-to-live, and most importantly the “data” field that holds the data published by your Spark core.
You are going to take advantage of the fact that a JSON can contain another JSON to send formatted data from your Spark core to the cloud.
Firmware Side
The firmware we need on the core is only slightly changed from the previous tutorial. All you need to do increase the size of the string buffer to hold more data and build the data string to publish in a bit more complicated way. The JSON format uses double-quote characters around all the names of the properties. For the values, you can use any normal value you would use but strings may need some escape character to not confuse the parser–check json.org for details.
Here is your core firmware. I named it publishjson.ino but you can call it whatever you like.
// publishjson.ino -- Spark Publishing Example
unsigned long lastTime = 0UL;
char publishString[64];
void setup() {
}
void loop() {
unsigned long now = millis();
//Every 15 seconds publish uptime
if (now-lastTime>15000UL) {
lastTime = now;
// now is in milliseconds
unsigned nowSec = now/1000UL;
unsigned sec = nowSec%60;
unsigned min = (nowSec%3600)/60;
unsigned hours = (nowSec%86400)/3600;
sprintf(publishString,"{\"Hours\": %u, \"Minutes\": %u, \"Seconds\": %u}",hours,min,sec);
Spark.publish("Uptime",publishString);
}
}
Notice that it is almost identical to the previous tutorial with just two changes: First off the publishString size has changed to 64 characters long. The second change is in the sprintf() that creates the publishString. The JSON data is surrounded by curly-braces ( {…} ) and all the names of the data fields have to be enclosed in double-quotes. How do you put double-quotes in a string for the sprintf function? Well in C/C++ you do this by using a backslash before the double-quote character, so when you sprintf something like "{\"Hours\":"
what you get out is just {"Hours":
.
The Javascript Web Side
Here is HTML file for the web side–it is every similar to the previous tutorial with one big exception we will talk about below. I called this Uptime2.html but you can pick any name.
Safety Note!
Because you put your access token in this file, you should never put it where other people can read it. Do not put it on a public webserver or in a public area like your public folder on Dropbox. This is private stuff just for you!
<!DOCTYPE HTML>
<html>
<body>
<span id="uptime"></span><br>
<span id="tstamp"></span>
<br><br>
<button onclick="start()">Connect</button>
<script type="text/javascript">
function start() {
document.getElementById("uptime").innerHTML = "Waiting for data...";
var deviceID = "<<your core id here>>";
var accessToken = "<<your access token here>>";
var eventSource = new EventSource("https://api.spark.io/v1/devices/" + deviceID + "/events/?access_token=" + accessToken);
eventSource.addEventListener('open', function(e) {
console.log("Opened!"); },false);
eventSource.addEventListener('error', function(e) {
console.log("Errored!"); },false);
eventSource.addEventListener('Uptime', function(e) {
var rawData = JSON.parse(e.data);
var parsedData = JSON.parse(rawData.data);
var tempSpan = document.getElementById("uptime");
var tsSpan = document.getElementById("tstamp");
tempSpan.innerHTML = "Core: " + rawData.coreid + " JSON Data: " + parsedData.Hours + ", " + parsedData.Minutes + ", " + parsedData.Seconds +
" (" + (parsedData.Seconds + parsedData.Minutes*60 + parsedData.Hours*3600) + " secs)";
tempSpan.style.fontSize = "28px";
tsSpan.innerHTML = "At timestamp " + rawData.published_at;
tsSpan.style.fontSize = "9px";
}, false);
}
</script>
</body>
</html>
The web side almost identical to the previous HTML file but you can see that there are now two JSON.parse calls. First you parse the raw data from the event. This has fields like “coreid” and “published_at” that you are using just like in the previous HTML file, but now the “data” field is not just a simple string. You call JSON.parse() on the data field of the rawData to get the three new fields for hours, minutes, and seconds. And since these are numbers now instead of strings, we can easily reassemble the time in seconds from the parts just by multiplying and adding.
OK, you are almost there. Open up Chrome or other recent browser on your PC and type this in the URL box, replacing the “<< >>” parts as to match you system:
For Windows: file:///C:/<<your path>>/Uptime2.html
For Mac: file:///users/<<your mac user name>>/<<your path>>/Uptime2.html
After you click the connect button, you should see something like this:
Go Play Some More!
Now you need to get out there and make your own JSON events. Just make sure your publishString is large enough to hold your data. In the coming days, the Spark team will add Arduino String objects which are dynamically allocated and you won’t have to worry so much about this. There will always be size limits on platforms like Spark and Arduino, just be aware that you cannot publish huge amounts of data.
You can also save your Uptime2.html file to a private folder on a service like Dropbox. Then on your phone, you can use the Dropbox app to open this file as a web page and see how your core is doing. Remember, do not put the Uptime2.html file in a public spot!