Ambient library. It provides "set" function to set data to a packet and "send" function to send the packet to the Ambient server. It also provides "bulk_send" function to send multiple data. (Japanese: IoT用のクラウドサービス「Ambient」のデーター送信ライブラリーです。Ambientはマイコンから送られたセンサーデーターを受信し、蓄積し、可視化(グラフ化)します。http://ambidata.io)

Dependents:   AmbientExampleSITB AmbientHeartRateMonitor AmbientHeartBeat AmbientExampleSITB_ws ... more

Ambient.cpp

Committer:
AmbientData
Date:
2017-01-25
Revision:
4:fcbd652bbb7a
Parent:
3:a724fe60de46

File content as of revision 4:fcbd652bbb7a:

#include "Ambient.h"

#define AMBIENT_DEBUG 0
#define SimpleIoTBoard 0

#if AMBIENT_DEBUG
#if SimpleIoTBoard
#include "SoftSerialSendOnry.h"
extern SoftSerialSendOnry pc;
#define DBG(...) { pc.printf(__VA_ARGS__); }
#define ERR(...) { pc.printf(__VA_ARGS__); }
#else
#define DBG(...) { printf(__VA_ARGS__); }
#define ERR(...) { printf(__VA_ARGS__); }
#endif /* SOFTSERIAL_SEND_ONRY_H */
#else
#define DBG(...)
#define ERR(...)
#endif /* AMBIENT_DEBUG */

const char* AMBIENT_HOST = "54.65.206.59";
const int AMBIENT_PORT = 80;
const char* AMBIENT_HOST_DEV = "192.168.0.6";
const int AMBIENT_PORT_DEV = 4567;

const char * ambient_keys[] = {"\"d1\":\"", "\"d2\":\"", "\"d3\":\"", "\"d4\":\"", "\"d5\":\"", "\"d6\":\"", "\"d7\":\"", "\"d8\":\"", "\"lat\":\"", "\"lng\":\"", "\"created\":\""};

Ambient::Ambient() {
}

bool
Ambient::init(unsigned int channelId, const char * writeKey, TCPSocketConnection * s, int dev) {
    this->channelId = channelId;

    if (sizeof(writeKey) > AMBIENT_WRITEKEY_SIZE) {
        ERR("writeKey length > AMBIENT_WRITEKEY_SIZE");
        return false;
    }
    strcpy(this->writeKey, writeKey);

    if(NULL == s) {
        ERR("Socket Pointer is NULL, open a socket.");
        return false;
    }
    this->s = s;
    this->dev = dev;
    if (dev) {
        strcpy(this->host, AMBIENT_HOST_DEV);
        this->port = AMBIENT_PORT_DEV;
    } else {
        strcpy(this->host, AMBIENT_HOST);
        this->port = AMBIENT_PORT;
    }
    for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) {
        this->data[i].set = false;
    }
    return true;
}

bool
Ambient::set(int field, char * data) {
    --field;
    if (field < 0 || field >= AMBIENT_NUM_PARAMS) {
        return false;
    }
    if (strlen(data) > AMBIENT_DATA_SIZE) {
        return false;
    }
    this->data[field].set = true;
    strcpy(this->data[field].item, data);

    return true;
}

bool
Ambient::set(int field, int data) {
    char buf[12];
    snprintf(buf, sizeof(buf), "%d", data);
    return (set(field, buf));
}

bool
Ambient::set(int field, double data) {
    char buf[12];
    snprintf(buf, sizeof(buf), "%f", data);
    return (set(field, buf));
}

bool
Ambient::clear(int field) {
    --field;
    if (field < 0 || field >= AMBIENT_NUM_PARAMS) {
        return false;
    }
    this->data[field].set = false;

    return true;
}

bool
Ambient::send() {

    int retry;
    for (retry = 0; retry < AMBIENT_MAX_RETRY; retry++) {
        int ret;
        ret = this->s->connect(this->host, this->port);
        if (ret == 0) {
            break ;
        }
    }
    if(retry == AMBIENT_MAX_RETRY) {
        ERR("Could not connect socket to host\r\n");
        return false;
    }

    char str[180];
    char body[192];

    memset(body, 0, sizeof(body));
    strcat(body, "{\"writeKey\":\"");
    strcat(body, this->writeKey);
    strcat(body, "\",");

    for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) {
        if (this->data[i].set) {
            strcat(body, ambient_keys[i]);
            strcat(body, this->data[i].item);
            strcat(body, "\",");
        }
    }
    body[strlen(body) - 1] = '\0';
    strcat(body, "}\r\n");

    memset(str, 0, sizeof(str));
    sprintf(str, "POST /api/v2/channels/%d/data HTTP/1.1\r\n", this->channelId);
    if (this->port == 80) {
        sprintf(&str[strlen(str)], "Host: %s\r\n", this->host);
    } else {
        sprintf(&str[strlen(str)], "Host: %s:%d\r\n", this->host, this->port);
    }
    sprintf(&str[strlen(str)], "Content-Length: %d\r\n", strlen(body));
    sprintf(&str[strlen(str)], "Content-Type: application/json\r\n\r\n");

    DBG("sending: %d bytes\r\n%s", strlen(str), str);

    int ret;
    ret = this->s->send_all(str, strlen(str));
    wait_ms(30);
    DBG("%d bytes sent\r\n", ret);
    if (ret < 0) {
        ERR("send failed\r\n");
        return false;
    }
    ret = this->s->send_all(body, strlen(body));
    wait_ms(30);
    DBG("%d bytes sent\r\n", ret);
    if (ret < 0) {
        ERR("send failed\r\n");
        return false;
    }

    ret = this->s->receive(str,sizeof(str));
    wait_ms(30);
    str[ret]=0;
    DBG("Received String : (%d)\r\n%s\r\n",ret, str);

    this->s->close();

    for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) {
        this->data[i].set = false;
    }

    return true;
}

int
Ambient::bulk_send(char *buf) {

    int retry;
    for (retry = 0; retry < AMBIENT_MAX_RETRY; retry++) {
        int ret;
        ret = this->s->connect(this->host, this->port);
        if (ret == 0) {
            break ;
        }
    }
    if(retry == AMBIENT_MAX_RETRY) {
        ERR("Could not connect socket to host\r\n");
        return -1;
    }

    char str[180];

    memset(str, 0, sizeof(str));
    sprintf(str, "POST /api/v2/channels/%d/dataarray HTTP/1.1\r\n", this->channelId);
    if (this->port == 80) {
        sprintf(&str[strlen(str)], "Host: %s\r\n", this->host);
    } else {
        sprintf(&str[strlen(str)], "Host: %s:%d\r\n", this->host, this->port);
    }
    sprintf(&str[strlen(str)], "Host: %s:%d\r\n", this->host, this->port);
    sprintf(&str[strlen(str)], "Content-Length: %d\r\n", strlen(buf));
    sprintf(&str[strlen(str)], "Content-Type: application/json\r\n\r\n");

    DBG("sending: %d bytes\r\n%s", strlen(str), str);

    int ret;
    ret = this->s->send_all(str, strlen(str)); // send header
    wait_ms(30);
    DBG("%d bytes sent\r\n", ret);
    if (ret < 0) {
        ERR("send failed\r\n");
        return -1;
    }
    int sent;
    sent = this->s->send_all(buf, strlen(buf));
    wait_ms(30);
    DBG("%d bytes sent\r\n", sent);
    if (sent < 0) {
        ERR("send failed\r\n");
        return -1;
    }

    ret = this->s->receive(str,sizeof(str));
    wait_ms(30);
    str[ret]=0;
    DBG("Received String : (%d)\r\n%s\r\n",ret, str);

    this->s->close();

    for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) {
        this->data[i].set = false;
    }

    return sent;
}

bool
Ambient::delete_data(const char * userKey) {
    int retry;
    for (retry = 0; retry < AMBIENT_MAX_RETRY; retry++) {
        int ret;
        ret = this->s->connect(this->host, this->port);
        if (ret == 0) {
            break ;
        }
    }
    if(retry == AMBIENT_MAX_RETRY) {
        ERR("Could not connect socket to host\r\n");
        return false;
    }

    char str[180];

    memset(str, 0, sizeof(str));
    sprintf(str, "DELETE /api/v2/channels/%d/data?userKey=%s HTTP/1.1\r\n", this->channelId, userKey);
    if (this->port == 80) {
        sprintf(&str[strlen(str)], "Host: %s\r\n", this->host);
    } else {
        sprintf(&str[strlen(str)], "Host: %s:%d\r\n", this->host, this->port);
    }
    sprintf(&str[strlen(str)], "Content-Length: 0\r\n");
    sprintf(&str[strlen(str)], "Content-Type: application/json\r\n\r\n");
    DBG("%s", str);

    int ret;
    ret = this->s->send_all(str, strlen(str));
    wait_ms(30);
    DBG("%d bytes sent\r\n", ret);
    if (ret < 0) {
        ERR("send failed\r\n");
        return false;
    }

    ret = this->s->receive(str,sizeof(str));
    str[ret]=0;
    DBG("Received String : (%d)\r\n%s\r\n",ret, str);

    this->s->close();

    for (int i = 0; i < AMBIENT_NUM_PARAMS; i++) {
        this->data[i].set = false;
    }

    return true;
}