SmartREST client reference implementation for the u-blox C027 mbed compatible device.
Dependencies: C027 C027_Support mbed mbed-rtos MbedSmartRest LM75B MMA7660 C12832
Fork of MbedSmartRestTest by
program.cpp
- Committer:
- vwochnik
- Date:
- 2014-07-03
- Revision:
- 35:ee1c6289e617
- Parent:
- 34:8a0556f39161
File content as of revision 35:ee1c6289e617:
#include "common.h" #include "io.h" #include "StaticData.h" #include "ComposedRecord.h" #include "CharValue.h" #include "IntegerValue.h" #include "FloatValue.h" #include "Aggregator.h" /************* CONFIGURATION *************/ /* Credentials for device bootstrap authentification. * Contact cumulocity to get credentials. */ #define DEVICEBOOTSTRAP_USERNAME "" #define DEVICEBOOTSTRAP_PASSWORD "" /* Uncomment and fill in credentials to turn off device bootstrapping. */ //#define CREDENTIALS_USERNAME "" //#define CREDENTIALS_PASSWORD "" /* Template device identifier */ #define TEMPLATE_DEVICE_IDENTIFIER "com_u-blox_C027_REV-A_0.10_Test1233123" /*****************************************/ bool deviceBootstrap(); long existing(); long create(); bool identify(long deviceId); bool update(long deviceId); void loop(long deviceId); void signalMeasurement(long deviceId, Aggregator& aggr); void temperatureMeasurement(long deviceId, Aggregator& aggr); void analogMeasurement(long deviceId, Aggregator& aggr); void motionMeasurement(long deviceId, Aggregator& aggr); credentials_t credentials = {}; char cDeviceIdentifier[48]; StaticData srtpl( // get device by identity // Usage: 100,<SERIAL/NR> "10,100,GET,/identity/externalIds/c8y_Serial/%%,,application/vnd.com.nsn.cumulocity.externalId+json,%%,STRING,\r\n" // get device id from identity // Response: 200,<DEVICE/ID> "11,200,\"$.managedObject\",,\"$.id\"\r\n" // Create device // Usage: 101,<SERIAL/NR> "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" // Get device id // Response: 201,<DEVICE/ID> "11,201,,\"$.c8y_IsDevice\",\"$.id\"\r\n" // Insert global ID // Usage: 102,<DEVICE/ID>,<SERIAL/NR> "10,102,POST,/identity/globalIds/%%/externalIds,application/vnd.com.nsn.cumulocity.externalId+json,application/vnd.com.nsn.cumulocity.externalId+json,%%,UNSIGNED STRING,\"{\"\"type\"\":\"\"c8y_Serial\"\",\"\"externalId\"\":\"\"%%\"\"}\"\r\n" // Update IMEI, CellId and iccid // Usage: 103,<DEVICE/ID>,<IMEI>,<CELL/ID>,<ICCID> "10,103,PUT,/inventory/managedObjects/%%,application/vnd.com.nsn.cumulocity.managedObject+json,application/vnd.com.nsn.cumulocity.managedObject+json,%%,UNSIGNED STRING STRING STRING,\"{\"\"c8y_Mobile\"\":{\"\"imei\"\":\"\"%%\"\",\"\"cellId\"\":\"\"%%\"\",\"\"iccid\"\":\"\"%%\"\"}}\"\r\n" // Insert measurement // USAGE: 104,<DEVICE/ID>,<RSSI>,<BER> "10,104,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER UNSIGNED,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_SignalStrength\"\",\"\"c8y_SignalStrength\"\":{\"\"rssi\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"dBm\"\"},\"\"ber\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"%\"\"}}}\"\r\n" // Insert measurement // USAGE: 105,<DEVICE/ID>,<TEMPERATURE> "10,105,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED NUMBER,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_TemperatureMeasurement\"\",\"\"c8y_TemperatureMeasurement\"\":{\"\"T\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"C\"\"}}}\"\r\n" // Insert measurement // USAGE: 105,<DEVICE/ID>,<ANALOG0>,<ANALOG1> "10,106,POST,/measurement/measurements,application/vnd.com.nsn.cumulocity.measurement+json,application/vnd.com.nsn.cumulocity.measurement+json,%%,NOW UNSIGNED UNSIGNED UNSIGNED,\"{\"\"time\"\":\"\"%%\"\",\"\"source\"\":{\"\"id\"\":\"\"%%\"\"},\"\"type\"\":\"\"c8y_AnalogMeasurement\"\",\"\"c8y_AnalogMeasurement\"\":{\"\"analog0\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"%\"\"},\"\"analog1\"\":{\"\"value\"\":%%,\"\"unit\"\":\"\"%\"\"}}}\"\r\n" // Insert measurement // USAGE: 105,<DEVICE/ID>,<X>,<Y>,<Z> "10,107,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" ); float interval = 120.0; // send measurements every two minutes MbedSmartRest client("developer.cumulocity.com", 80, credentials.username, credentials.password, cDeviceIdentifier); int program(void) { long deviceId = 0; Timer timer; #ifndef CREDENTIALS_USERNAME // read credentials from modem or make a device bootstrapping if (!credentials_read(&credentials)) { puts("Could not read credentials. Starting bootstrapping process."); if (!deviceBootstrap()) { puts("Device bootstrap failed."); return 1; } } #else // copy hardcoded credentials strcpy(credentials.username, CREDENTIALS_USERNAME); strcpy(credentials.password, CREDENTIALS_PASSWORD); #endif // copy identifier into variable strcpy(cDeviceIdentifier, TEMPLATE_DEVICE_IDENTIFIER); lcd_tenant(credentials.username); puts("Hello!"); puts("Bootstrapping"); lcd_status("Bootstrapping"); if (client.bootstrap(srtpl) != SMARTREST_SUCCESS) { puts("Bootstrapping failed."); lcd_status("Bootstrapping failed."); return 2; } puts("Starting action..."); if ((deviceId = existing()) == 0) { if (((deviceId = create()) == 0) || (!identify(deviceId))) { lcd_status("Device creation failed."); return 1; } } update(deviceId); printf("Device ID: %ld\r\n", deviceId); timer.start(); while (true) { timer.reset(); loop(deviceId); lcd_status("Sleeping..."); // block remaining number of seconds while (timer.read() < interval) { Thread::yield(); } } } bool deviceBootstrap() { uint8_t ret; ComposedRecord record(false); ParsedRecord received; CharValue deviceId(imei()); IntegerValue connectMsgId(60); IntegerValue pollMsgId(61); // copy credentials strcpy(credentials.username, DEVICEBOOTSTRAP_USERNAME); strcpy(credentials.password, DEVICEBOOTSTRAP_PASSWORD); record.add(connectMsgId); record.add(deviceId); if (client.send(record) != SMARTREST_SUCCESS) { puts("Could not connect to platform."); client.stop(); return false; } client.stop(); ret = client.receive(received); if (ret == SMARTREST_SUCCESS) { if ((received.values() > 0) && (received.value(0).integerValue() == 50)) puts("Server error. Make sure to register the device before attempting a device bootstrap."); else puts("Unknown error."); return false; } record.clear(); record.add(pollMsgId); record.add(deviceId); while (true) { if (client.send(record) != SMARTREST_SUCCESS) { puts("Connection unsuccessful. Retrying."); client.stop(); Thread::wait(2000); continue; } if (client.receive(received) != SMARTREST_SUCCESS) { puts("Not received anything. Retrying."); client.stop(); Thread::wait(2000); continue; } client.stop(); if (received.values() < 1) { puts("Bad received values. Retrying."); Thread::wait(2000); continue; } if (received.value(0).integerValue() == 50) { puts("No values. Retrying."); Thread::wait(2000); continue; } if (received.value(0).integerValue() != 70) { puts("Unknown received message identifier."); return false; } if (received.values() != 6) { puts("Bad credentials received."); return false; } credentials_set(&credentials, received.value(3).characterValue(), received.value(4).characterValue(), received.value(5).characterValue()); printf("Username: %s\nPassword: %s\n", credentials.username, credentials.password); credentials_write(&credentials); return true; } } long existing() { ComposedRecord newMoRec(true); // set copy=true b/c tmp objects ParsedRecord received; lcd_status("Checking device existance..."); puts("Checking for device existance..."); if ((!newMoRec.add(IntegerValue(100))) || (!newMoRec.add(CharValue(imei())))) return 0; if (client.send(newMoRec) != SMARTREST_SUCCESS) { puts("Send failed."); client.stop(); return 0; } if (client.receive(received) != SMARTREST_SUCCESS) { puts("No device found."); client.stop(); return 0; } if (received.values() == 0) { puts("Received no values."); client.stop(); return 0; } if (received.value(0).integerValue() == 50) { client.stop(); return 0; } if (received.value(0).integerValue() != 200) { puts("Bad response."); client.stop(); return 0; } client.stop(); return received.value(2).integerValue(); } long create() { ComposedRecord newMoRec(true); // set copy=true b/c tmp objects ParsedRecord received; lcd_status("Creating device..."); puts("Creating device..."); if ((!newMoRec.add(IntegerValue(101))) || (!newMoRec.add(CharValue(imei())))) return 0; if (client.send(newMoRec) != SMARTREST_SUCCESS) { puts("Send failed."); client.stop(); return 0; } if (client.receive(received) != SMARTREST_SUCCESS) { puts("No device found."); client.stop(); return 0; } if (received.values() != 3) { puts("Bad received data."); client.stop(); return 0; } if (received.value(0).integerValue() != 201) { puts("Bad received data."); client.stop(); return 0; } client.stop(); return received.value(2).integerValue(); } bool identify(long deviceId) { ComposedRecord newMoRec(true); // set copy=true b/c tmp objects ParsedRecord received; puts("Adding global identifier..."); if ((!newMoRec.add(IntegerValue(102))) || (!newMoRec.add(IntegerValue(deviceId))) || (!newMoRec.add(CharValue(imei())))) return 0; if (client.send(newMoRec) != SMARTREST_SUCCESS) { puts("Sending failed."); client.stop(); return false; } if (client.receive(received) != SMARTREST_SUCCESS) { puts("Failed."); client.stop(); return false; } if (received.values() != 3) { puts("Received bad data."); client.stop(); return false; } if (received.value(0).integerValue() != 200) { puts("Received bad data."); client.stop(); return false; } client.stop(); return true; } bool update(long deviceId) { ComposedRecord newMoRec(true); // set copy=true b/c tmp objects ParsedRecord received; lcd_status("Updating device object..."); puts("Updating device data..."); if ((!newMoRec.add(IntegerValue(103))) || (!newMoRec.add(IntegerValue(deviceId))) || (!newMoRec.add(CharValue(imei()))) || (!newMoRec.add(CharValue(cellId()))) || (!newMoRec.add(CharValue(iccid())))) return false; if (client.send(newMoRec) != SMARTREST_SUCCESS) { puts("Send failed."); client.stop(); return false; } if (client.receive(received) != SMARTREST_SUCCESS) { puts("Update failed."); client.stop(); return false; } if (received.values() != 3) { puts("Bad received data."); client.stop(); return false; } if (received.value(0).integerValue() != 201) { puts("Bad received data."); client.stop(); return false; } client.stop(); return true; } void loop(long deviceId) { Aggregator aggr(true); lcd_status("Sending measurements..."); temperatureMeasurement(deviceId, aggr); signalMeasurement(deviceId, aggr); analogMeasurement(deviceId, aggr); motionMeasurement(deviceId, aggr); if (client.send(aggr) != SMARTREST_SUCCESS) { puts("Loop send failed."); } client.stop(); } void signalMeasurement(long deviceId, Aggregator& aggr) { sigq_t *sq = signalQuality(); if ((sq->rssi == 0) || (sq->ber == 0)) return; ComposedRecord measurement; IntegerValue msgId(104); IntegerValue devId(deviceId); FloatValue rssi(sq->rssi, 0); IntegerValue ber(sq->ber); if ((!measurement.add(msgId)) || (!measurement.add(devId)) || (!measurement.add(rssi)) || (!measurement.add(ber))) return; aggr.add(measurement); } void temperatureMeasurement(long deviceId, Aggregator& aggr) { ComposedRecord measurement; IntegerValue msgId(105); IntegerValue devId(deviceId); FloatValue temp(temperature(), 1); if ((!measurement.add(msgId)) || (!measurement.add(devId)) || (!measurement.add(temp))) return; aggr.add(measurement); } void analogMeasurement(long deviceId, Aggregator& aggr) { long analog0 = (long)(potentiometer(0) * 100.0); long analog1 = (long)(potentiometer(1) * 100.0); ComposedRecord measurement; IntegerValue msgId(106); IntegerValue devId(deviceId); IntegerValue an0(analog0); IntegerValue an1(analog1); if ((!measurement.add(msgId)) || (!measurement.add(devId)) || (!measurement.add(an0)) || (!measurement.add(an1))) return; aggr.add(measurement); } void motionMeasurement(long deviceId, Aggregator& aggr) { acceleration_t acc = acceleration(); ComposedRecord measurement; IntegerValue msgId(107); IntegerValue devId(deviceId); FloatValue x(acc.x, 2); FloatValue y(acc.y, 2); FloatValue z(acc.z, 2); if ((!measurement.add(msgId)) || (!measurement.add(devId)) || (!measurement.add(x)) || (!measurement.add(y)) || (!measurement.add(z))) return; aggr.add(measurement); }