Junichi Katsu
/
IFTTT_Temperature
Simpe IoT BoardにGrove温度センサを繋げてIFTTTにプッシュするプログラムです。
Diff: IFTTT/ifttt.cpp
- Revision:
- 0:26b07836cf44
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/IFTTT/ifttt.cpp Fri Nov 13 07:55:43 2015 +0000 @@ -0,0 +1,223 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "ifttt.h" +//#include <string> +#include "SoftSerialSendOnry.h" + +extern SoftSerialSendOnry pc; + +#if 0 +#define DBG(x, ...) pc.printf("[IFTTT : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); +#define WARN(x, ...) pc.printf("[IFTTT : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); +#define ERR(x, ...) pc.printf("[IFTTT : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); +#else +#define DBG(x, ...) //wait_us(10); +#define WARN(x, ...) //wait_us(10); +#define ERR(x, ...) +#endif + +#if 0 +#define INFO(x, ...) pc.printf("[IFTTT : INFO]"x" \r\n",##__VA_ARGS__); +#else +#define INFO(x, ...) +#endif + +// +// Initialize object with Event, Key, and valid socket. +// TODO: accept hostname parameter / implement DNS lookup +// +IFTTT::IFTTT(const char * event, const char * key, TCPSocketConnection * s) +{ + // Error Check + if(sizeof(event) > IFTTT_MAX_SIZE_EVENTNAME) { + ERR("Given event > IFTTT_MAX_SIZE_EVENTNAME, increase the max event string size in ifttt.h"); + } + if(sizeof(key) > IFTTT_MAX_SIZE_SECRETKEY) { + ERR("Given key > IFTTT_MAX_SIZE_SECRETKEY, increase the max secret key string size in ifttt.h"); + } + // Copy event name and secret key into object instance + strcpy(this->eventName,event); + strcpy(this->secretKey,key); + + // Set up Socket + if(NULL == s) { + WARN("Given Socket Pointer is NULL, will try opening a socket."); + } + this->socket = s; + + // Set up Host / Port + this->port = IFTTT_PORT; + this->host = IFTTT_IP; + + // Initialize ingredient values to empty strings. + v1 = ""; + v2 = ""; + v3 = ""; +} + +// +// Add ingredients to be sent. +// +bool +IFTTT::addIngredients( char * value1, char * value2, char * value3) +{ + // update internal pointers. If variable not given then pass an empty string + v1 = (NULL == value1)?"":value1; + v2 = (NULL == value2)?"":value2; + v3 = (NULL == value3)?"":value3; + return true; +} + +// +// This function sends data to maker.ifttt.org via GET query commands +// return true on sucess, false on fail +// +bool IFTTT::get() +{ + // Connect to maker.ifttt.org + int retry = 0; + for(retry=0; retry<IFTTT_MAX_RETRY; retry++) { + int ret = this->socket->connect(this->host, this->port); + if(ret == 0) { + DBG("Successfully Connected socket to host"); + break ; + } + } + if(retry == IFTTT_MAX_RETRY) { + this->socket->close(); + ERR("Could not connect socket to host\r\n"); + return false; + } + + // Prep data to send + // TODO: verify / modify data to be query string compliant (convert spaces to '+', convert non-alpha-numberic characters to the proper encoding... etc) + char str[IFTTT_MAX_SIZE_STRING] = {0}; + sprintf(str, "GET /trigger/%s/with/key/%s/?value1=%s&value2=%s&value3=%s HTTP/1.1\r\nHost: maker.ifttt.com\r\n\r\n",eventName,secretKey,v1,v2,v3); + DBG("String to send is:\n\r%s",str); + + // Send Data + DBG("Sending GET data..."); + int check = 0; + check = this->socket->send_all(str,sizeof(str)); + if(check) { + DBG("Sent Sucessfully %d bytes",check); + } else { + ERR("Sending failed"); + return false; + } + DBG("Waiting on reply ... \r\n"); + int ret = this->socket->receive(str,50); + str[ret]=0; + DBG("Received String : %s",str); + this->socket->close(); + + return true; +} + +// +// This function sends JSON encoded data encoded in a POST packet, +// +bool IFTTT::post() +{ + // Connect to maker.ifttt.org + int retry = 0; + for(retry=0; retry<IFTTT_MAX_RETRY; retry++) { + int ret = this->socket->connect(this->host, this->port); + if(ret == 0) { + DBG("Successfully Connected socket to host"); + break ; + } + } + if(retry == IFTTT_MAX_RETRY) { + this->socket->close(); + ERR("Could not connect socket to host\r\n"); + return false; + } + + // Prep data to send, the Assembled POST packet should look like this + // + // + //POST /trigger/<eventName>/with/key/<secretKey> HTTP/1.1 + //Host: maker.ifttt.com + //Content-Length: <length of POST data> + //Content-Type: application/json + // + //{"value1":"<v1>","value2":"<v2>","value3":"<v3>"} + // + // + char str[IFTTT_MAX_SIZE_STRING] = {0}; + char header[100] = {0}; + sprintf(header, "POST /trigger/%s/with/key/%s HTTP/1.1\r\n",eventName,secretKey); + const char * host = "Host: maker.ifttt.com\r\n"; + char contentLen[50] = {0}; + const char * contentType = "Content-Type: application/json\r\n\r\n"; + char valueData [150] = {0}; + sprintf(valueData,"{\"value1\":\"%s\",\"value2\":\"%s\",\"value3\":\"%s\"}\r\n",v1,v2,v3); + sprintf(contentLen,"Content-Length: %d\r\n",strlen(valueData)); + sprintf(str,"%s%s%s%s%s",header,host,contentLen,contentType,valueData); + + DBG("String to send is:\n\r%s",str); + + // Send Data + DBG("Sending POST data..."); + int check = 0; + check = this->socket->send_all(str,strlen(str)); + if(check) { + DBG("Sent Sucessfully %d bytes",check); + } else { + ERR("Sending failed"); + return false; + } + DBG("Waiting on reply ... \r\n"); + int ret = this->socket->receive(str,IFTTT_MAX_SIZE_STRING); + str[ret]=0; + DBG("Received String : %s",str); + this->socket->close(); + + return true; +} + +// +// Send trigger and any values associated to maker.ifttt.com +// currently unsecured (sends over HTTP, not https) +// +bool +IFTTT::trigger(int triggerType) +{ + int ret = 0; + switch(triggerType) { + case IFTTT_GET: + DBG("Sending Data as GET request"); + ret = get(); + break; + case IFTTT_POST: + DBG("Sending Data as POST request"); + ret = post(); + break; + + default: + WARN("Invalid type, defaulting to sending data as POST request"); + ret = post(); + break; + } + DBG("Sending Data return code : %d",ret); + if(ret){ + INFO("Successfully triggered event: '%s' with v1='%s', v2='%s', v3='%s' !",eventName,v1,v2,v3); + } + return ret; +}