Ambient Library
Fork of AmbientLib by
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)
Revision 0:d2972e5edb22, committed 2016-05-07
- Comitter:
- TakehikoShimojima
- Date:
- Sat May 07 01:11:27 2016 +0000
- Commit message:
- initial
Changed in this revision
Ambient.cpp | Show annotated file Show diff for this revision Revisions of this file |
Ambient.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Ambient.cpp Sat May 07 01:11:27 2016 +0000 @@ -0,0 +1,147 @@ +#include "Ambient.h" + +#define _DEBUG 0 + +#if _DEBUG +#define DBG(...) { printf(__VA_ARGS__); } +#define ERR(...) { printf(__VA_ARGS__); } +#else +#define DBG(...) +#define ERR(...) +#endif /* _DBG */ + +const char* AMBIENT_HOST = "54.65.206.59"; +const int AMBIENT_PORT = 80; +const char* AMBIENT_HOST_DEV = "192.168.0.8"; +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::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[360] = {0}; + char header[54] = {0}; + char host[32] = {0}; + char contentLen[28] = {0}; + const char *contentType = "Content-Type: application/json\r\n\r\n"; + char body[192] = {0}; + + 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"); + + sprintf(header, "POST /api/v2/channels/%d/data HTTP/1.1\r\n", this->channelId); + if (this->port == 80) { + sprintf(host, "Host: %s\r\n", this->host); + } else { + sprintf(host, "Host: %s:%d\r\n", this->host, this->port); + } + sprintf(contentLen, "Content-Length: %d\r\n", strlen(body)); + sprintf(str, "%s%s%s%s%s", header, host, contentLen, contentType, body); + + 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->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; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Ambient.h Sat May 07 01:11:27 2016 +0000 @@ -0,0 +1,112 @@ +#ifndef AMBIENT_H +#define AMBIENT_H + +#include "mbed.h" +#include "TCPSocketConnection.h" + +#define AMBIENT_WRITEKEY_SIZE 18 +#define AMBIENT_MAX_RETRY 5 +#define AMBIENT_DATA_SIZE 24 +#define AMBIENT_NUM_PARAMS 11 + +/** AMBIENT class + * to send data to Ambient service. + * + * Exsample: + * @code + * #include "mbed.h" + * #include "EthernetInterface.h" + * #include "Ambient.h" + * #include "HDC1000.h" + * + * unsigned int channelId = 100; + * const char* writeKey = "ライトキー"; + * AMBIENT ambient; + * + * HDC1000 hdc1000(p9,p10); + * + * int main() { + * printf("start\r\n"); + * + * EthernetInterface eth; + * eth.init(); //Use DHCP + * eth.connect(); + * + * TCPSocketConnection socket; + * ambient.init(channelId, writeKey, &socket); + * + * printf("Ambient send to ch: %d\r\n", channelId); + * + * while (true) { + * float temp, humid; + * char tempbuf[12], humidbuf[12]; + * + * hdc1000.get(); + * temp = hdc1000.temperature(); + * humid = hdc1000.humidity(); + * + * sprintf(tempbuf, "%2.1f", temp); + * ambient.set(1, tempbuf); + * sprintf(humidbuf, "%2.0f", humid); + * ambient.set(2, humidbuf); + * printf("Temp: %s C, Humid: %s %%\r\n", tempbuf, humidbuf); + * + * ambient.send(); + * + * wait(30.0); + * } + * } + * @endcode + */ +class AMBIENT +{ +public: + /** Create AMBIENT instance + */ + AMBIENT(void); + + /** Initialize the instance + * @param channelId Initialize the Ambient instance with channelId. + * @param writeKey and writeKey + * @param s and pointer to socket + * @returns + * true on success, + * false on error + */ + bool init(unsigned int channelId, const char * writeKey, TCPSocketConnection * s, int dev = 0); + /** Set data on field-th field of payload. + * @param field index of payload (1 to 8) + * @param data data + * @returns + * true on success, + * false on error + */ + bool set(int field, char * data); + /** Clear data on field-th field of payload. + * @param field index of payload (1 to 8) + * @returns + * true on success, + * false on error + */ + bool clear(int field); + + /** Send data to Ambient + */ + bool send(void); + +private: + + TCPSocketConnection * s; + unsigned int channelId; + char writeKey[AMBIENT_WRITEKEY_SIZE]; + int dev; + char host[18]; + int port; + + struct { + int set; + char item[AMBIENT_DATA_SIZE]; + } data[AMBIENT_NUM_PARAMS]; +}; + +#endif // AMBIENT_H \ No newline at end of file