demo project

Dependencies:   AX-12A Dynamixel mbed iothub_client EthernetInterface NTPClient ConfigFile SDFileSystem iothub_amqp_transport mbed-rtos proton-c-mbed wolfSSL

Revision:
18:224289104fc0
Parent:
17:0dbcbd8587fd
Child:
19:2f0ec9ac1238
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Utils/IothubSerial.cpp	Sat Jan 23 00:08:30 2016 +0000
@@ -0,0 +1,271 @@
+#include "mbed.h"
+#include "IothubSerial.h"
+#include "crt_abstractions.h"
+
+const char* nametemp = "temp";
+const char* namevolt = "volt";
+const char* namedeg = "rot";
+const char* nameload = "load";
+
+IothubSerial::IothubSerial()
+{
+    _hasPending = false;
+}
+
+// try to serialize the measurements into the buffer
+// return bytes used or -1 if buffer too small or other error
+// current serialization is a json array with ',' at end
+//  eg: temp: [22.0, 23.1, 22.3],
+int IothubSerial::MeasureGroupToString(const char* name, MeasureGroup& mg, char* buf, int bufsize)
+{
+    int slen;
+    int startlen = bufsize;
+    
+    slen = sprintf_s(buf, bufsize, "\"%s\": [", name);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+       
+    for (int i = 0; i < mg.NumVals; i++)
+    {
+        if (i < mg.NumVals - 1)
+            slen = sprintf_s(buf, bufsize, "%.2f, ", mg.MeasVals[i]);
+        else
+            slen = sprintf_s(buf, bufsize, "%.2f ", mg.MeasVals[i]);
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+        }
+        else
+            return -1;
+    }
+    
+    slen = sprintf_s(buf, bufsize, "],");
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+    
+    return startlen - bufsize;
+}
+
+int AddTime(time_t seconds, char* buf, int bufsize)
+{
+    if (bufsize > 32)
+    {
+        int slen = strftime(buf, 32, "\"time\": \"%FT%T\",", localtime(&seconds));
+        if (slen > 0)
+        {
+            return slen;
+        }
+        else
+            return -1;
+    }        
+    else
+        return -1;
+}
+
+
+// try to serialize a snapshot into the buffer
+// return bytes used / -1 if buffer too small / 0 if no data
+// current serialization is a json object with time and array per measure
+// eg: { "time": "2016-01-23T14:55:02", "temp": [1, 2], "volt": [12.1, 12.2] }
+int IothubSerial::MeasureSnapshotToString(MeasureSnapshot& msnap, char* buf, int bufsize)
+{
+    int slen;
+    int startlen = bufsize;
+
+    slen = sprintf_s(buf, bufsize, "{");
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    slen = AddTime(msnap.Created, buf, bufsize);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    slen = MeasureGroupToString(nametemp, msnap.Temps, buf, bufsize);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    slen = MeasureGroupToString(namedeg, msnap.Positions, buf, bufsize);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    slen = MeasureGroupToString(nameload, msnap.Loads, buf, bufsize);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    slen = MeasureGroupToString(namevolt, msnap.Volts, buf, bufsize);
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+
+    // replace final ',' with '}'
+    *(buf - 1) = '}';
+    
+    return startlen - bufsize;
+}
+
+// try to serialize one or more measurement snapshots into the buffer
+// return bytes used / -1 if buffer too small / 0 if no data
+// current serialization is a json array of objects with time and array per measure
+// eg: [{ "time": "2016-01-23T14:55:02", "temp": [1, 2], "volt": [12.1, 12.2] }]
+int IothubSerial::MeasureBufToString(char* buf, int bufsize)
+{
+    int slen;
+    bool hasdata = false;
+    bool copydata = false;
+    char* startbuf = buf;
+    char* lastcomma = NULL;
+    
+    slen = sprintf_s(buf, bufsize, "[");
+    if (slen > 0)
+    {
+        bufsize -= slen;
+        buf += slen;
+    }
+    else
+        return -1;
+ 
+    if (_hasPending)
+    {
+        hasdata = true;
+        slen = MeasureSnapshotToString(_pending, buf, bufsize);
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+        }
+        else
+            return -1;          // no room for pending record
+        // add comma
+        slen = sprintf_s(buf, bufsize, ",");
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+        }
+        else
+            return -1;
+        lastcomma = buf;
+        _hasPending = false;
+        copydata = true;
+    }
+    
+    while (!MeasureBuf.empty())
+    {
+        if (!MeasureBuf.pop(_pending))
+        {
+            break;
+        }
+        hasdata = true;
+        _hasPending = true;
+        
+        slen = MeasureSnapshotToString(_pending, buf, bufsize);
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+        }
+        else
+            break;              // no room to serialize, leave pending for next message
+        // add comma
+        slen = sprintf_s(buf, bufsize, ",");
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+        }
+        else
+            break;
+        _hasPending = false;
+        lastcomma = buf;
+        copydata = true;
+    }
+    
+    if (!hasdata)
+        return 0;               // no data
+        
+    if (!copydata)
+        return -1;              // have data but buffer too small
+
+    // replace final ',' with ']'
+    *(lastcomma - 1) = ']';
+    
+    return lastcomma - startbuf;
+}
+
+
+// try to serialize one or more alerts into the buffer
+// return bytes used or -1 if buffer too small or other error. 0 if no data
+// Serialize to a json object with time, measurename, value, message, and index of joint
+// eg: { "alerttype": "Temperature", "message": "too hot", "measurename", "temp", "index": 2, "value": 79.3, "time": "2016-01-23T14:55:02" }
+int IothubSerial::AlertBufToString(char* buf, int bufsize)
+{
+    int slen;
+    bool hasdata = false;
+    bool copydata = false;
+    int startlen = bufsize;
+ 
+    if (AlertBuf.pop(_pendAlert))
+    {
+        char tbuf[32];
+        (void)strftime(tbuf, 32, "%FT%T", localtime(&_pendAlert.Created));
+        hasdata = true;
+        slen = sprintf_s(buf, bufsize, "{ \"alerttype\": \"%s\", \"message\": \"%s\", \"measurename\": \"%s\",  \"index\": %d ,  \"value\": %f, \"time\": \"%s\" }", 
+                                            _pendAlert.AlertType, _pendAlert.Msg, _pendAlert.MeasureName, _pendAlert.Index, _pendAlert.Value, tbuf);
+        if (slen > 0)
+        {
+            bufsize -= slen;
+            buf += slen;
+            copydata = true;
+        }
+    }
+    
+    if (!hasdata)
+        return 0;               // no data
+        
+    if (!copydata)
+        return -1;              // have data but buffer too small
+
+
+    return startlen - bufsize;
+}
+