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 Vincent Wochnik

program.cpp

Committer:
vwochnik
Date:
2014-04-16
Revision:
25:8604bef314c1
Parent:
24:8f9b678a7932
Child:
26:26e9899e2cbe

File content as of revision 25:8604bef314c1:

#include "common.h"
#include "io.h"
#include "StaticData.h"
#include "ComposedRecord.h"
#include "CharValue.h"
#include "IntegerValue.h"
#include "FloatValue.h"
#include "Aggregator.h"

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);

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, "vaillant/admin", "klanpi", "com_u-blox_C027_REV-A_0.10_Test1233123");
//MbedSmartRest client("vsrv41584.customer.xenway.de", 8888, "vaillant/admin", "klanpi", "com_u-blox_C027_REV-A_0.10_Test123");

int program(void)
{
    long deviceId = 0; Timer timer;

    lcd_tenant("vaillant");
    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();
        }
    }
}

long existing()
{
    ComposedRecord newMoRec(true); // set copy=true b/c tmp objects
    ParsedRecord received;

    lcd_status("Checking device existance...");
    puts("Checking for device existance...");

    newMoRec.add(IntegerValue(100)).add(CharValue(imei()));

    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...");

    newMoRec.add(IntegerValue(101)).add(CharValue(imei()));

    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...");

    newMoRec.add(IntegerValue(102)).add(IntegerValue(deviceId)).add(CharValue(imei()));

    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...");

    newMoRec.add(IntegerValue(103)).add(IntegerValue(deviceId)).add(CharValue(imei())).add(CharValue(cellId())).add(CharValue(iccid()));

    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(8, false, true);

    lcd_status("Sending measurements...");
    signalMeasurement(deviceId, aggr);
    if (client.send(aggr) != SMARTREST_SUCCESS) {
        puts("Loop send failed.");
    }
    client.stop();
    aggr.clear();
    temperatureMeasurement(deviceId, aggr);
    if (client.send(aggr) != SMARTREST_SUCCESS) {
        puts("Loop send failed.");
    }
    client.stop();
    aggr.clear();
    analogMeasurement(deviceId, aggr);
    if (client.send(aggr) != SMARTREST_SUCCESS) {
        puts("Loop send failed.");
    }
    client.stop();
    aggr.clear();
    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);
    measurement.add(msgId).add(devId).add(rssi).add(ber);
    aggr.add(measurement);
}

void temperatureMeasurement(long deviceId, Aggregator& aggr)
{
    ComposedRecord measurement;
    IntegerValue msgId(105);
    IntegerValue devId(deviceId);
    FloatValue temp(temperature(), 1);
    measurement.add(msgId).add(devId).add(temp);
    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);
    measurement.add(msgId).add(devId).add(an0).add(an1);
    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);
    measurement.add(msgId).add(devId).add(x).add(y).add(z);
    aggr.add(measurement);
}