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

operation/OperationExecutor.cpp

Committer:
xinlei
Date:
2015-03-20
Revision:
92:48069375dffa
Parent:
91:423177e8a401
Child:
93:0acd11870c6a

File content as of revision 92:48069375dffa:

#include <string.h>
#include <stdio.h>
#include "OperationExecutor.h"
#include "ComposedRecord.h"
#include "CharValue.h"
#include "IntegerValue.h"
#include "logging.h"

#define FOUND_RELAY 1
#define FOUND_MESSAGE 2
#define FOUND_CONFIGURATION 3

OperationExecutor::OperationExecutor(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId, 
                                     ConfigurationSynchronization& configurationSynchronization, DeviceIO& io,
                                     DisplayInfo& displayInfo) :
    _init(false),
    _deviceId(deviceId),
    _tpl(tpl),
    _client(client),
    _configurationSynchronization(configurationSynchronization),
    _io(io),
    _displayInfo(displayInfo)
{
}

bool OperationExecutor::init()
{
    if (_init)
        return false;
    
    // Get operation by id
    // USAGE: 112,<OPERATION/ID>
    if (!_tpl.add("10,112,GET,/devicecontrol/operations/%%,,application/vnd.com.nsn.cumulocity.operation+json,%%,UNSIGNED,\r\n"))
        return false;

    // Relay operation response
    // Response: 220,<OPERATION/ID>,<STATUS>
    if (!_tpl.add("11,220,,\"$.c8y_Relay\",\"$.id\",\"$.c8y_Relay.relayState\"\r\n"))
        return false;

    // Message operation response
    // Response: 221,<OPERATION/ID>,<MESSAGE>
    if (!_tpl.add("11,221,,\"$.c8y_Message\",\"$.id\",\"$.c8y_Message.text\"\r\n"))
        return false;

    // Configuration operation response
    // Response: 222,<OPERATION/ID>,<CONFIGURATION/STRING>
    if (!_tpl.add("11,222,,\"$.c8y_Configuration\",\"$.id\",\"$.c8y_Configuration.config\"\r\n"))
        return false;

    _init = true;
    return true;
}

bool OperationExecutor::executeOperation(OperationStore::Operation& op)
{
    ComposedRecord record;
    ParsedRecord received;
    
    IntegerValue msgId(112);
    IntegerValue operationId(op.identifier);
    if ((!record.add(msgId)) || (!record.add(operationId)))
        return false;
    
    if (_client.send(record) != SMARTREST_SUCCESS) {
        _client.stop();
        return false;
    }
    
    uint8_t found = 0;
    bool relayState;
    char message[256];
    while (_client.receive(received) == SMARTREST_SUCCESS) {
        if ((received.values() == 4) &&
            (received.value(0).valueType() == VALUE_INTEGER) &&
            (received.value(0).integerValue() == 220) &&
            (received.value(2).valueType() == VALUE_INTEGER) &&
            (received.value(2).integerValue() == op.identifier) &&
            (received.value(3).valueType() == VALUE_CHARACTER)) {
            relayState = strcmp("CLOSED", received.value(3).characterValue()) == 0;
            found = FOUND_RELAY;
            break;
        }       
        if ((received.values() == 4) &&
            (received.value(0).valueType() == VALUE_INTEGER) &&
            (received.value(0).integerValue() == 221) &&
            (received.value(2).valueType() == VALUE_INTEGER) &&
            (received.value(2).integerValue() == op.identifier) &&
            (received.value(3).valueType() == VALUE_CHARACTER)) {
            strncpy(message, received.value(3).characterValue(), 128);
            message[127] = '\0';
            found = FOUND_MESSAGE;
            break;
        }
        if ((received.values() == 4) &&
            (received.value(0).valueType() == VALUE_INTEGER) &&
            (received.value(0).integerValue() == 222) &&
            (received.value(2).valueType() == VALUE_INTEGER) &&
            (received.value(2).integerValue() == op.identifier) &&
            (received.value(3).valueType() == VALUE_CHARACTER)) {
            strncpy(message, received.value(3).characterValue(), 256);
            message[255] = '\0';
            found = FOUND_CONFIGURATION;
            break;
        }
    }
    _client.stop();

    switch (found) {
    case FOUND_RELAY:         return executeRelayStateUpdate(relayState);
    case FOUND_MESSAGE:       return executeMessageDisplay(message);
    case FOUND_CONFIGURATION: return executeUpdateConfiguration(message);
    default:
        aWarning("Unsupported configuration received.\r\n");
        if (getLevel() == A_DEBUG) {
            aDebug("Configuration received: \r\n");
            for (size_t q = 0; q < received.values(); q++)
                aDebug("\t%s", received.rawValue(q));
        }
        return false;
    }
}

bool OperationExecutor::executeRelayStateUpdate(bool relayState)
{
    if (relayState)
        _io.deviceFeedback().closeRelay();
    else
        _io.deviceFeedback().openRelay();
    return true;
}

bool OperationExecutor::executeMessageDisplay(const char *message)
{
//    char msg[78];   // Length of text that the LCD display can hold
//    strncpy(msg, message, sizeof(msg));
//    _io.lcdPrint(msg);
    extern bool lastSensorReadingSent;
    _displayInfo.setFirstLine(message);
    puts("setted first line");
    _io.lcdPrint(message);
    puts("printed io message");
    lastSensorReadingSent=true;
    return true;
}

bool OperationExecutor::executeUpdateConfiguration(const char *config)
{
    return _configurationSynchronization.updateConfiguration(config);
}