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
Revision 47:89ae46d5c466, committed 2014-07-24
- 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
--- 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.");