Official reference client implementation for Cumulocity SmartREST on u-blox C027.

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

Files at this revision

API Documentation at this revision

Comitter:
Cumulocity
Date:
Thu Jul 24 23:32:53 2014 +0000
Parent:
46:f6976fd64387
Child:
48:d5e21301543e
Commit message:
major update

Changed in this revision

AccelerationMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
AnalogMeasurement.cpp Show annotated file Show diff for this revision Revisions of this file
AnalogMeasurement.h Show annotated file Show diff for this revision Revisions of this file
C027_Support.lib Show annotated file Show diff for this revision Revisions of this file
DeviceIO.cpp Show annotated file Show diff for this revision Revisions of this file
DeviceIO.h Show annotated file Show diff for this revision Revisions of this file
DeviceIntegration.cpp Show annotated file Show diff for this revision Revisions of this file
GPSTracker.cpp Show annotated file Show diff for this revision Revisions of this file
GPSTracker.h Show annotated file Show diff for this revision Revisions of this file
LocationUpdate.cpp Show annotated file Show diff for this revision Revisions of this file
LocationUpdate.h Show annotated file Show diff for this revision Revisions of this file
MbedAgent.cpp Show annotated file Show diff for this revision Revisions of this file
MbedAgent.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/AccelerationMeasurement.cpp	Thu Jul 24 16:02:47 2014 +0000
+++ b/AccelerationMeasurement.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -19,7 +19,7 @@
         return false;
     
     // Insert measurement
-    // USAGE: 105,<DEVICE/ID>,<X>,<Y>,<Z>
+    // USAGE: 106,<DEVICE/ID>,<X>,<Y>,<Z>
     if (!_tpl.add("10,106,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_MotionMeasurement\"\",\"\"c8y_MotionMeasurement\"\":{\"\"x\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m^2/s\"\"},\"\"y\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m^2/s\"\"},\"\"z\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"m^2/s\"\"}}}\"\r\n"))
         return false;
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AnalogMeasurement.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,48 @@
+#include "AnalogMeasurement.h"
+#include "ComposedRecord.h"
+#include "CharValue.h"
+#include "IntegerValue.h"
+#include "FloatValue.h"
+
+AnalogMeasurement::AnalogMeasurement(SmartRest& client, SmartRestTemplate& tpl, long& deviceId, AnalogIn& analog1, AnalogIn& analog2) :
+    _client(client),
+    _tpl(tpl),
+    _deviceId(deviceId),
+    _analog1(analog1),
+    _analog2(analog2)
+{
+    _init = false;
+}
+
+bool AnalogMeasurement::init()
+{
+    if (_init)
+        return false;
+    
+    // Insert measurement
+    // USAGE: 107,<DEVICE/ID>,<ANALOG1>,<ANALOG2>
+    if (!_tpl.add("10,107,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_AnalogMeasurement\"\",\"\"c8y_AnalogMeasurement\"\":{\"\"A1\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"},\"\"A2\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"A\"\"}}}\"\r\n"))
+        return false;
+
+    _init = true;
+    return true;
+}
+
+bool AnalogMeasurement::run()
+{
+    ComposedRecord record;
+    IntegerValue msgId(107);
+    IntegerValue devId(_deviceId);
+    FloatValue analog1(_analog1.read(), 1);
+    FloatValue analog2(_analog2.read(), 1);
+    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(analog1)) || (!record.add(analog2)))
+        return false;
+
+    if (_client.send(record) != SMARTREST_SUCCESS) {
+        puts("Signal measurement failed.");
+        _client.stop();
+        return false;
+    }
+    _client.stop();
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AnalogMeasurement.h	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,25 @@
+#ifndef ANALOGMEASUREMENT_H
+#define ANALOGMEASUREMENT_H
+
+#include "SmartRest.h"
+#include "SmartRestTemplate.h"
+#include "mbed.h"
+
+class AnalogMeasurement
+{
+public:
+    AnalogMeasurement(SmartRest&, SmartRestTemplate&, long&, AnalogIn&, AnalogIn&);
+    
+    bool init();
+    bool run();
+
+private:
+    bool _init;
+    long& _deviceId;
+    SmartRestTemplate& _tpl;
+    SmartRest& _client;
+    AnalogIn& _analog1;
+    AnalogIn& _analog2;
+};
+
+#endif
\ No newline at end of file
--- a/C027_Support.lib	Thu Jul 24 16:02:47 2014 +0000
+++ b/C027_Support.lib	Thu Jul 24 23:32:53 2014 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/teams/ublox/code/C027_Support/#71e3b8bc9ab8
+http://mbed.org/teams/ublox/code/C027_Support/#c64ba749a422
--- a/DeviceIO.cpp	Thu Jul 24 16:02:47 2014 +0000
+++ b/DeviceIO.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -1,7 +1,10 @@
 #include "DeviceIO.h"
 
-DeviceIO::DeviceIO() :
+DeviceIO::DeviceIO(GPSI2C& gps) :
+    _gpsTracker(gps),
     _resetButton(D4), // fire button on arduino app shield
+    _analog1(A0),
+    _analog2(A1),
     _temperatureSensor(SDA,SCL),
     _accelerometer(SDA,SCL),
     _lcd(D11, D13, D12, D7, D10)
@@ -13,6 +16,20 @@
     return _resetButton;
 }
 
+GPSTracker& DeviceIO::gpsTracker()
+{
+    return _gpsTracker;
+}
+
+AnalogIn& DeviceIO::analog1()
+{
+    return _analog1;
+}
+
+AnalogIn& DeviceIO::analog2()
+{
+    return _analog2;
+}
 LM75B& DeviceIO::temperatureSensor()
 {
     return _temperatureSensor;
--- a/DeviceIO.h	Thu Jul 24 16:02:47 2014 +0000
+++ b/DeviceIO.h	Thu Jul 24 23:32:53 2014 +0000
@@ -2,6 +2,8 @@
 #define DEVICEIO_H
 
 #include "mbed.h"
+#include "GPSTracker.h"
+#include "GPS.h"
 #include "LM75B.h"
 #include "MMA7660.h"
 #include "C12832.h"
@@ -35,15 +37,21 @@
 class DeviceIO
 {
 public:
-    DeviceIO();
+    DeviceIO(GPSI2C&);
 
     bool resetButtonPressed();
+    GPSTracker& gpsTracker();
+    AnalogIn& analog1();
+    AnalogIn& analog2();
     LM75B& temperatureSensor();
     MMA7660& accelerometer();
     void lcdPrint(const char*, const char* = NULL, const char* = NULL);
 
 private:
+    GPSTracker _gpsTracker;
     DigitalIn _resetButton;
+    AnalogIn _analog1;
+    AnalogIn _analog2;
     LM75B _temperatureSensor;
     MMA7660 _accelerometer;
     C12832 _lcd;
--- a/DeviceIntegration.cpp	Thu Jul 24 16:02:47 2014 +0000
+++ b/DeviceIntegration.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -30,7 +30,7 @@
 
     // Create device
     // Usage: 101,<SERIAL/NR>
-    if (!_tpl.add("10,101,POST,/inventory/managedObjects,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,STRING,\"{\"\"name\"\":\"\"Mbed Test Device\"\",\"\"type\"\":\"\"com_ublox_C027_REV-A\"\",\"\"c8y_Hardware\"\":{\"\"revision\"\":\"\"1\"\",\"\"model\"\":\"\"Ublox C027\"\",\"\"serialNumber\"\":\"\"%%\"\"},\"\"c8y_SupportedMeasurements\"\":[\"\"c8y_SignalStrength\"\",\"\"c8y_TemperatureMeasurement\"\",\"\"c8y_AnalogMeasurement\"\",\"\"c8y_MotionMeasurement\"\"],\"\"c8y_RequiredAvailability\"\":{ \"\"responseInterval\"\":15},\"\"c8y_IsDevice\"\":{}}\"\r\n"))
+    if (!_tpl.add("10,101,POST,/inventory/managedObjects,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,STRING,\"{\"\"name\"\":\"\"Mbed Test Device\"\",\"\"type\"\":\"\"com_ublox_C027_REV-A\"\",\"\"c8y_Hardware\"\":{\"\"revision\"\":\"\"1\"\",\"\"model\"\":\"\"Ublox C027\"\",\"\"serialNumber\"\":\"\"%%\"\"},\"\"c8y_SupportedMeasurements\"\":[\"\"c8y_SignalStrength\"\",\"\"c8y_TemperatureMeasurement\"\",\"\"c8y_AnalogMeasurement\"\",\"\"c8y_MotionMeasurement\"\",\"\"c8y_AnalogMeasurement\"\"],\"\"c8y_RequiredAvailability\"\":{ \"\"responseInterval\"\":15},\"\"c8y_IsDevice\"\":{}}\"\r\n"))
         return false;
 
     // Get device id
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPSTracker.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,75 @@
+#include "GPSTracker.h"
+#include <stdlib.h>
+#include <string.h>
+
+GPSTracker::GPSTracker(GPSI2C& gps) :
+    _gps(gps),
+    _thread(GPSTracker::thread_func, this),
+    _positionSet(false)
+{
+}
+
+bool GPSTracker::position(GPSTracker::Position *position)
+{
+    bool result;
+    
+    _mutex.lock();
+    if (_positionSet) {
+        memcpy(position, &_position, sizeof(GPSTracker::Position));
+        _positionSet = false;
+        result = true;
+    } else {
+        result = false;
+    }
+    _mutex.unlock();
+    
+    return result;
+}
+    
+void GPSTracker::thread()
+{
+    char buf[256], chr; // needs to be that big otherwise mdm isn't working
+    int ret, len, n;
+    double altitude, latitude, longitude;
+    
+    while (true) {
+        ret = _gps.getMessage(buf, sizeof(buf));
+        if (ret <= 0) {
+            Thread::wait(100);
+            continue;
+        }
+        
+        len = LENGTH(ret);
+        if ((PROTOCOL(ret) != GPSParser::NMEA) || (len <= 6))
+            continue;
+
+        // we're only interested in fixed GPS positions
+        // we are not interested in invalid data
+        if ((strncmp("$GPGGA", buf, 6) != 0) ||
+            (!_gps.getNmeaItem(6, buf, len, n, 10)) || (n == 0))
+            continue;
+        
+        // get altitude, latitude and longitude
+        if ((!_gps.getNmeaAngle(2, buf, len, latitude)) ||
+            (!_gps.getNmeaAngle(4, buf, len, longitude)) ||
+            (!_gps.getNmeaItem(9, buf, len, altitude)) ||
+            (!_gps.getNmeaItem(10, buf, len, chr)) ||
+            (chr != 'M'))
+            continue;
+
+        _mutex.lock();
+        _position.altitude = altitude;
+        _position.latitude = latitude;
+        _position.longitude = longitude;
+        _positionSet = true;
+        _mutex.unlock();
+    }
+}
+
+void GPSTracker::thread_func(void const *arg)
+{
+    GPSTracker *that;
+    return;
+    that = (GPSTracker*)arg;
+    that->thread();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GPSTracker.h	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,45 @@
+#ifndef GPSTRACKER_H
+#define GPSTRACKER_H
+
+#include <stddef.h>
+#include "GPS.h"
+#include "rtos.h"
+
+/**
+ * A GPS tracker class providing access to the current position.
+ */
+class GPSTracker
+{
+public:
+    /**
+     * Initialize a new GPSTracker object.
+     * @param gps a previously initialized instance of the GPSI2C class
+     */
+    GPSTracker(GPSI2C&);
+    
+    typedef struct {
+        double altitude;  // altitude  meters
+        double latitude;  // latitude  degrees
+        double longitude; // longitude degrees
+    } Position;
+    
+    /**
+     * Retrieves and invalidates the current position.
+     * @param position a pointer of type Position where the current position is written to
+     * @return true on success, false otherwise
+     */
+    bool position(Position*);
+    
+protected:
+    void thread();
+    static void thread_func(void const*);
+
+private:
+    GPSI2C _gps;
+    Thread _thread;
+    Mutex _mutex;
+    Position _position;
+    bool _positionSet;
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LocationUpdate.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,66 @@
+#include "LocationUpdate.h"
+#include "ComposedRecord.h"
+#include "CharValue.h"
+#include "IntegerValue.h"
+#include "FloatValue.h"
+
+LocationUpdate::LocationUpdate(SmartRest& client, SmartRestTemplate& tpl, long& deviceId, GPSTracker& gpsTracker) :
+    _client(client),
+    _tpl(tpl),
+    _deviceId(deviceId),
+    _gpsTracker(gpsTracker)
+{
+    _init = false;
+}
+
+bool LocationUpdate::init()
+{
+    if (_init)
+        return false;
+    
+    // Insert measurement
+    // USAGE: 108,<DEVICE/ID>,<ALTITUDE>,<LATITUDE>,<LONGITUDE>
+    if (!_tpl.add("10,108,POST,/event/events,application/vnd.com.nsn.cumulocity.event+json,,%%,NOW UNSIGNED NUMBER NUMBER NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_LocationUpdate\"\",\"\"c8y_Position\"\":{\"\"alt\"\":%%,\"\"lat\"\":%%,\"\"lng\"\":%%}}\""))
+        return false;
+
+    _init = true;
+    return true;
+}
+
+bool LocationUpdate::run()
+{
+    GPSTracker::Position position;
+    
+    if (!_gpsTracker.position(&position))
+        return true;
+        
+    puts("Starting measurement sending.");
+    
+    ComposedRecord record;
+    IntegerValue msgId(108);
+    IntegerValue devId(_deviceId);
+    FloatValue altitude(position.altitude, 6);
+    FloatValue latitude(position.latitude, 6);
+    FloatValue longitude(position.longitude, 1);
+    if ((!record.add(msgId)) || (!record.add(devId)) || (!record.add(altitude)) || (!record.add(latitude)) || (!record.add(longitude)))
+        return false;
+
+    if (_client.send(record) != SMARTREST_SUCCESS) {
+        puts("Signal measurement failed.");
+        _client.stop();
+        return false;
+    }
+    
+    ParsedRecord recvd;
+    if (_client.receive(recvd) != SMARTREST_SUCCESS) {
+        puts("Nothing received.");
+        _client.stop();
+        return true;
+    }
+    
+    for (size_t n = 0; n < recvd.values(); n++)
+        puts(recvd.rawValue(n));
+    
+    _client.stop();
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LocationUpdate.h	Thu Jul 24 23:32:53 2014 +0000
@@ -0,0 +1,24 @@
+#ifndef LOCATIONUPDATE_H
+#define LOCATIONUPDATE_H
+
+#include "SmartRest.h"
+#include "SmartRestTemplate.h"
+#include "GPSTracker.h"
+
+class LocationUpdate
+{
+public:
+    LocationUpdate(SmartRest&, SmartRestTemplate&, long&, GPSTracker&);
+    
+    bool init();
+    bool run();
+
+private:
+    bool _init;
+    long& _deviceId;
+    SmartRestTemplate& _tpl;
+    SmartRest& _client;
+    GPSTracker& _gpsTracker;
+};
+
+#endif
\ No newline at end of file
--- a/MbedAgent.cpp	Thu Jul 24 16:02:47 2014 +0000
+++ b/MbedAgent.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -11,6 +11,8 @@
     _signalQualityMeasurement(_client, _tpl, _deviceId, _deviceInfo),
     _temperatureMeasurement(_client, _tpl, _deviceId, _io.temperatureSensor()),
     _accelerationMeasurement(_client, _tpl, _deviceId, _io.accelerometer()),
+    _analogMeasurement(_client, _tpl, _deviceId, _io.analog1(), _io.analog2()),
+    _locationUpdate(_client, _tpl, _deviceId, _io.gpsTracker()),
     _deviceId(0)
 {
 }
@@ -20,7 +22,9 @@
     if ((!_integration.init()) ||
         (!_signalQualityMeasurement.init()) ||
         (!_temperatureMeasurement.init()) ||
-        (!_accelerationMeasurement.init())) {
+        (!_accelerationMeasurement.init()) ||
+        (!_analogMeasurement.init()) ||
+        (!_locationUpdate.init())) {
         puts("Initialization failed.");
         return false;
     }
@@ -62,9 +66,13 @@
     while (true) {
         timer.reset();
         
-        _signalQualityMeasurement.run();
+        puts("Sending signal quality.");
+        if (!_signalQualityMeasurement.run())
+            puts("Failed signal str.");
         _temperatureMeasurement.run();
         _accelerationMeasurement.run();
+        _analogMeasurement.run();
+        _locationUpdate.run();
         
         while (timer.read() < MBED_AGENT_INTERVAL) {
             Thread::yield();
--- a/MbedAgent.h	Thu Jul 24 16:02:47 2014 +0000
+++ b/MbedAgent.h	Thu Jul 24 23:32:53 2014 +0000
@@ -12,10 +12,12 @@
 #include "SignalQualityMeasurement.h"
 #include "TemperatureMeasurement.h"
 #include "AccelerationMeasurement.h"
+#include "AnalogMeasurement.h"
+#include "LocationUpdate.h"
 
 #define MBED_AGENT_HOST "developer.cumulocity.com"
 #define MBED_AGENT_PORT 80
-#define MBED_AGENT_DEVICE_IDENTIFIER "com_cumulocity_MbedAgent_1.0.0"
+#define MBED_AGENT_DEVICE_IDENTIFIER "com_cumulocity_MbedAgent_1.0.3"
 #define MBED_AGENT_INTERVAL 60.0
 
 class MbedAgent
@@ -40,6 +42,8 @@
     SignalQualityMeasurement _signalQualityMeasurement;
     TemperatureMeasurement _temperatureMeasurement;
     AccelerationMeasurement _accelerationMeasurement;
+    AnalogMeasurement _analogMeasurement;
+    LocationUpdate _locationUpdate;
     long _deviceId;
 };
 
--- a/main.cpp	Thu Jul 24 16:02:47 2014 +0000
+++ b/main.cpp	Thu Jul 24 23:32:53 2014 +0000
@@ -1,28 +1,38 @@
 #include "mbed.h"
 #include "rtos.h"
 #include "MDM.h"
+#include "GPS.h"
 #include "DeviceInfo.h"
 #include "MbedAgent.h"
 #include "apndb.h"
+#include "GPSTracker.h"
 
 int main()
 {
     MDMParser::DevStatus devStatus;
-    DeviceIO io;
     int res;
 
-    io.lcdPrint("DEVICE INIT");
-
     MDMSerial mdm;
+    GPSI2C gps;
     //mdm.setDebug(4);
 
     if (!mdm.init(NULL, &devStatus)) {
         puts("Modem initialization failed. Check your PIN number.");
-        io.lcdPrint("MODEM INIT FAILURE");
+        return 1;
+    }
+    puts("Modem initialized");
+
+    /*if (!gps.init()) {
+        puts("GPS initialization failed.");
         return 1;
     }
+    puts("Gps initialized.");*/
+    
+    DeviceIO io(gps);
+    io.lcdPrint("DEVICE INIT");
     
     if (io.resetButtonPressed()) {
+        puts("Resetting program.");
         res = mdm.delFile("001_CREDENTIALS");
         if (res < 0) {
             puts("Credential reset failed.");
@@ -47,6 +57,7 @@
         io.lcdPrint("NO APN FOUND", "IMEI:", devStatus.imsi);
         return 1;
     }
+    puts("Connected.");
     
     if (!mdm.registerNet()) {
         puts("Network registration failed.");