Junichi Katsu
/
IFTTT_Temperature
Simpe IoT BoardにGrove温度センサを繋げてIFTTTにプッシュするプログラムです。
IFTTT/ifttt.cpp@0:26b07836cf44, 2015-11-13 (annotated)
- Committer:
- jksoft
- Date:
- Fri Nov 13 07:55:43 2015 +0000
- Revision:
- 0:26b07836cf44
??
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jksoft | 0:26b07836cf44 | 1 | /* mbed Microcontroller Library |
jksoft | 0:26b07836cf44 | 2 | * Copyright (c) 2006-2013 ARM Limited |
jksoft | 0:26b07836cf44 | 3 | * |
jksoft | 0:26b07836cf44 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
jksoft | 0:26b07836cf44 | 5 | * you may not use this file except in compliance with the License. |
jksoft | 0:26b07836cf44 | 6 | * You may obtain a copy of the License at |
jksoft | 0:26b07836cf44 | 7 | * |
jksoft | 0:26b07836cf44 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
jksoft | 0:26b07836cf44 | 9 | * |
jksoft | 0:26b07836cf44 | 10 | * Unless required by applicable law or agreed to in writing, software |
jksoft | 0:26b07836cf44 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
jksoft | 0:26b07836cf44 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
jksoft | 0:26b07836cf44 | 13 | * See the License for the specific language governing permissions and |
jksoft | 0:26b07836cf44 | 14 | * limitations under the License. |
jksoft | 0:26b07836cf44 | 15 | */ |
jksoft | 0:26b07836cf44 | 16 | |
jksoft | 0:26b07836cf44 | 17 | #include "mbed.h" |
jksoft | 0:26b07836cf44 | 18 | #include "ifttt.h" |
jksoft | 0:26b07836cf44 | 19 | //#include <string> |
jksoft | 0:26b07836cf44 | 20 | #include "SoftSerialSendOnry.h" |
jksoft | 0:26b07836cf44 | 21 | |
jksoft | 0:26b07836cf44 | 22 | extern SoftSerialSendOnry pc; |
jksoft | 0:26b07836cf44 | 23 | |
jksoft | 0:26b07836cf44 | 24 | #if 0 |
jksoft | 0:26b07836cf44 | 25 | #define DBG(x, ...) pc.printf("[IFTTT : DBG]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); |
jksoft | 0:26b07836cf44 | 26 | #define WARN(x, ...) pc.printf("[IFTTT : WARN]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); |
jksoft | 0:26b07836cf44 | 27 | #define ERR(x, ...) pc.printf("[IFTTT : ERR]"x" \t[%s,%d]\r\n", ##__VA_ARGS__,__FILE__,__LINE__); |
jksoft | 0:26b07836cf44 | 28 | #else |
jksoft | 0:26b07836cf44 | 29 | #define DBG(x, ...) //wait_us(10); |
jksoft | 0:26b07836cf44 | 30 | #define WARN(x, ...) //wait_us(10); |
jksoft | 0:26b07836cf44 | 31 | #define ERR(x, ...) |
jksoft | 0:26b07836cf44 | 32 | #endif |
jksoft | 0:26b07836cf44 | 33 | |
jksoft | 0:26b07836cf44 | 34 | #if 0 |
jksoft | 0:26b07836cf44 | 35 | #define INFO(x, ...) pc.printf("[IFTTT : INFO]"x" \r\n",##__VA_ARGS__); |
jksoft | 0:26b07836cf44 | 36 | #else |
jksoft | 0:26b07836cf44 | 37 | #define INFO(x, ...) |
jksoft | 0:26b07836cf44 | 38 | #endif |
jksoft | 0:26b07836cf44 | 39 | |
jksoft | 0:26b07836cf44 | 40 | // |
jksoft | 0:26b07836cf44 | 41 | // Initialize object with Event, Key, and valid socket. |
jksoft | 0:26b07836cf44 | 42 | // TODO: accept hostname parameter / implement DNS lookup |
jksoft | 0:26b07836cf44 | 43 | // |
jksoft | 0:26b07836cf44 | 44 | IFTTT::IFTTT(const char * event, const char * key, TCPSocketConnection * s) |
jksoft | 0:26b07836cf44 | 45 | { |
jksoft | 0:26b07836cf44 | 46 | // Error Check |
jksoft | 0:26b07836cf44 | 47 | if(sizeof(event) > IFTTT_MAX_SIZE_EVENTNAME) { |
jksoft | 0:26b07836cf44 | 48 | ERR("Given event > IFTTT_MAX_SIZE_EVENTNAME, increase the max event string size in ifttt.h"); |
jksoft | 0:26b07836cf44 | 49 | } |
jksoft | 0:26b07836cf44 | 50 | if(sizeof(key) > IFTTT_MAX_SIZE_SECRETKEY) { |
jksoft | 0:26b07836cf44 | 51 | ERR("Given key > IFTTT_MAX_SIZE_SECRETKEY, increase the max secret key string size in ifttt.h"); |
jksoft | 0:26b07836cf44 | 52 | } |
jksoft | 0:26b07836cf44 | 53 | // Copy event name and secret key into object instance |
jksoft | 0:26b07836cf44 | 54 | strcpy(this->eventName,event); |
jksoft | 0:26b07836cf44 | 55 | strcpy(this->secretKey,key); |
jksoft | 0:26b07836cf44 | 56 | |
jksoft | 0:26b07836cf44 | 57 | // Set up Socket |
jksoft | 0:26b07836cf44 | 58 | if(NULL == s) { |
jksoft | 0:26b07836cf44 | 59 | WARN("Given Socket Pointer is NULL, will try opening a socket."); |
jksoft | 0:26b07836cf44 | 60 | } |
jksoft | 0:26b07836cf44 | 61 | this->socket = s; |
jksoft | 0:26b07836cf44 | 62 | |
jksoft | 0:26b07836cf44 | 63 | // Set up Host / Port |
jksoft | 0:26b07836cf44 | 64 | this->port = IFTTT_PORT; |
jksoft | 0:26b07836cf44 | 65 | this->host = IFTTT_IP; |
jksoft | 0:26b07836cf44 | 66 | |
jksoft | 0:26b07836cf44 | 67 | // Initialize ingredient values to empty strings. |
jksoft | 0:26b07836cf44 | 68 | v1 = ""; |
jksoft | 0:26b07836cf44 | 69 | v2 = ""; |
jksoft | 0:26b07836cf44 | 70 | v3 = ""; |
jksoft | 0:26b07836cf44 | 71 | } |
jksoft | 0:26b07836cf44 | 72 | |
jksoft | 0:26b07836cf44 | 73 | // |
jksoft | 0:26b07836cf44 | 74 | // Add ingredients to be sent. |
jksoft | 0:26b07836cf44 | 75 | // |
jksoft | 0:26b07836cf44 | 76 | bool |
jksoft | 0:26b07836cf44 | 77 | IFTTT::addIngredients( char * value1, char * value2, char * value3) |
jksoft | 0:26b07836cf44 | 78 | { |
jksoft | 0:26b07836cf44 | 79 | // update internal pointers. If variable not given then pass an empty string |
jksoft | 0:26b07836cf44 | 80 | v1 = (NULL == value1)?"":value1; |
jksoft | 0:26b07836cf44 | 81 | v2 = (NULL == value2)?"":value2; |
jksoft | 0:26b07836cf44 | 82 | v3 = (NULL == value3)?"":value3; |
jksoft | 0:26b07836cf44 | 83 | return true; |
jksoft | 0:26b07836cf44 | 84 | } |
jksoft | 0:26b07836cf44 | 85 | |
jksoft | 0:26b07836cf44 | 86 | // |
jksoft | 0:26b07836cf44 | 87 | // This function sends data to maker.ifttt.org via GET query commands |
jksoft | 0:26b07836cf44 | 88 | // return true on sucess, false on fail |
jksoft | 0:26b07836cf44 | 89 | // |
jksoft | 0:26b07836cf44 | 90 | bool IFTTT::get() |
jksoft | 0:26b07836cf44 | 91 | { |
jksoft | 0:26b07836cf44 | 92 | // Connect to maker.ifttt.org |
jksoft | 0:26b07836cf44 | 93 | int retry = 0; |
jksoft | 0:26b07836cf44 | 94 | for(retry=0; retry<IFTTT_MAX_RETRY; retry++) { |
jksoft | 0:26b07836cf44 | 95 | int ret = this->socket->connect(this->host, this->port); |
jksoft | 0:26b07836cf44 | 96 | if(ret == 0) { |
jksoft | 0:26b07836cf44 | 97 | DBG("Successfully Connected socket to host"); |
jksoft | 0:26b07836cf44 | 98 | break ; |
jksoft | 0:26b07836cf44 | 99 | } |
jksoft | 0:26b07836cf44 | 100 | } |
jksoft | 0:26b07836cf44 | 101 | if(retry == IFTTT_MAX_RETRY) { |
jksoft | 0:26b07836cf44 | 102 | this->socket->close(); |
jksoft | 0:26b07836cf44 | 103 | ERR("Could not connect socket to host\r\n"); |
jksoft | 0:26b07836cf44 | 104 | return false; |
jksoft | 0:26b07836cf44 | 105 | } |
jksoft | 0:26b07836cf44 | 106 | |
jksoft | 0:26b07836cf44 | 107 | // Prep data to send |
jksoft | 0:26b07836cf44 | 108 | // TODO: verify / modify data to be query string compliant (convert spaces to '+', convert non-alpha-numberic characters to the proper encoding... etc) |
jksoft | 0:26b07836cf44 | 109 | char str[IFTTT_MAX_SIZE_STRING] = {0}; |
jksoft | 0:26b07836cf44 | 110 | 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); |
jksoft | 0:26b07836cf44 | 111 | DBG("String to send is:\n\r%s",str); |
jksoft | 0:26b07836cf44 | 112 | |
jksoft | 0:26b07836cf44 | 113 | // Send Data |
jksoft | 0:26b07836cf44 | 114 | DBG("Sending GET data..."); |
jksoft | 0:26b07836cf44 | 115 | int check = 0; |
jksoft | 0:26b07836cf44 | 116 | check = this->socket->send_all(str,sizeof(str)); |
jksoft | 0:26b07836cf44 | 117 | if(check) { |
jksoft | 0:26b07836cf44 | 118 | DBG("Sent Sucessfully %d bytes",check); |
jksoft | 0:26b07836cf44 | 119 | } else { |
jksoft | 0:26b07836cf44 | 120 | ERR("Sending failed"); |
jksoft | 0:26b07836cf44 | 121 | return false; |
jksoft | 0:26b07836cf44 | 122 | } |
jksoft | 0:26b07836cf44 | 123 | DBG("Waiting on reply ... \r\n"); |
jksoft | 0:26b07836cf44 | 124 | int ret = this->socket->receive(str,50); |
jksoft | 0:26b07836cf44 | 125 | str[ret]=0; |
jksoft | 0:26b07836cf44 | 126 | DBG("Received String : %s",str); |
jksoft | 0:26b07836cf44 | 127 | this->socket->close(); |
jksoft | 0:26b07836cf44 | 128 | |
jksoft | 0:26b07836cf44 | 129 | return true; |
jksoft | 0:26b07836cf44 | 130 | } |
jksoft | 0:26b07836cf44 | 131 | |
jksoft | 0:26b07836cf44 | 132 | // |
jksoft | 0:26b07836cf44 | 133 | // This function sends JSON encoded data encoded in a POST packet, |
jksoft | 0:26b07836cf44 | 134 | // |
jksoft | 0:26b07836cf44 | 135 | bool IFTTT::post() |
jksoft | 0:26b07836cf44 | 136 | { |
jksoft | 0:26b07836cf44 | 137 | // Connect to maker.ifttt.org |
jksoft | 0:26b07836cf44 | 138 | int retry = 0; |
jksoft | 0:26b07836cf44 | 139 | for(retry=0; retry<IFTTT_MAX_RETRY; retry++) { |
jksoft | 0:26b07836cf44 | 140 | int ret = this->socket->connect(this->host, this->port); |
jksoft | 0:26b07836cf44 | 141 | if(ret == 0) { |
jksoft | 0:26b07836cf44 | 142 | DBG("Successfully Connected socket to host"); |
jksoft | 0:26b07836cf44 | 143 | break ; |
jksoft | 0:26b07836cf44 | 144 | } |
jksoft | 0:26b07836cf44 | 145 | } |
jksoft | 0:26b07836cf44 | 146 | if(retry == IFTTT_MAX_RETRY) { |
jksoft | 0:26b07836cf44 | 147 | this->socket->close(); |
jksoft | 0:26b07836cf44 | 148 | ERR("Could not connect socket to host\r\n"); |
jksoft | 0:26b07836cf44 | 149 | return false; |
jksoft | 0:26b07836cf44 | 150 | } |
jksoft | 0:26b07836cf44 | 151 | |
jksoft | 0:26b07836cf44 | 152 | // Prep data to send, the Assembled POST packet should look like this |
jksoft | 0:26b07836cf44 | 153 | // |
jksoft | 0:26b07836cf44 | 154 | // |
jksoft | 0:26b07836cf44 | 155 | //POST /trigger/<eventName>/with/key/<secretKey> HTTP/1.1 |
jksoft | 0:26b07836cf44 | 156 | //Host: maker.ifttt.com |
jksoft | 0:26b07836cf44 | 157 | //Content-Length: <length of POST data> |
jksoft | 0:26b07836cf44 | 158 | //Content-Type: application/json |
jksoft | 0:26b07836cf44 | 159 | // |
jksoft | 0:26b07836cf44 | 160 | //{"value1":"<v1>","value2":"<v2>","value3":"<v3>"} |
jksoft | 0:26b07836cf44 | 161 | // |
jksoft | 0:26b07836cf44 | 162 | // |
jksoft | 0:26b07836cf44 | 163 | char str[IFTTT_MAX_SIZE_STRING] = {0}; |
jksoft | 0:26b07836cf44 | 164 | char header[100] = {0}; |
jksoft | 0:26b07836cf44 | 165 | sprintf(header, "POST /trigger/%s/with/key/%s HTTP/1.1\r\n",eventName,secretKey); |
jksoft | 0:26b07836cf44 | 166 | const char * host = "Host: maker.ifttt.com\r\n"; |
jksoft | 0:26b07836cf44 | 167 | char contentLen[50] = {0}; |
jksoft | 0:26b07836cf44 | 168 | const char * contentType = "Content-Type: application/json\r\n\r\n"; |
jksoft | 0:26b07836cf44 | 169 | char valueData [150] = {0}; |
jksoft | 0:26b07836cf44 | 170 | sprintf(valueData,"{\"value1\":\"%s\",\"value2\":\"%s\",\"value3\":\"%s\"}\r\n",v1,v2,v3); |
jksoft | 0:26b07836cf44 | 171 | sprintf(contentLen,"Content-Length: %d\r\n",strlen(valueData)); |
jksoft | 0:26b07836cf44 | 172 | sprintf(str,"%s%s%s%s%s",header,host,contentLen,contentType,valueData); |
jksoft | 0:26b07836cf44 | 173 | |
jksoft | 0:26b07836cf44 | 174 | DBG("String to send is:\n\r%s",str); |
jksoft | 0:26b07836cf44 | 175 | |
jksoft | 0:26b07836cf44 | 176 | // Send Data |
jksoft | 0:26b07836cf44 | 177 | DBG("Sending POST data..."); |
jksoft | 0:26b07836cf44 | 178 | int check = 0; |
jksoft | 0:26b07836cf44 | 179 | check = this->socket->send_all(str,strlen(str)); |
jksoft | 0:26b07836cf44 | 180 | if(check) { |
jksoft | 0:26b07836cf44 | 181 | DBG("Sent Sucessfully %d bytes",check); |
jksoft | 0:26b07836cf44 | 182 | } else { |
jksoft | 0:26b07836cf44 | 183 | ERR("Sending failed"); |
jksoft | 0:26b07836cf44 | 184 | return false; |
jksoft | 0:26b07836cf44 | 185 | } |
jksoft | 0:26b07836cf44 | 186 | DBG("Waiting on reply ... \r\n"); |
jksoft | 0:26b07836cf44 | 187 | int ret = this->socket->receive(str,IFTTT_MAX_SIZE_STRING); |
jksoft | 0:26b07836cf44 | 188 | str[ret]=0; |
jksoft | 0:26b07836cf44 | 189 | DBG("Received String : %s",str); |
jksoft | 0:26b07836cf44 | 190 | this->socket->close(); |
jksoft | 0:26b07836cf44 | 191 | |
jksoft | 0:26b07836cf44 | 192 | return true; |
jksoft | 0:26b07836cf44 | 193 | } |
jksoft | 0:26b07836cf44 | 194 | |
jksoft | 0:26b07836cf44 | 195 | // |
jksoft | 0:26b07836cf44 | 196 | // Send trigger and any values associated to maker.ifttt.com |
jksoft | 0:26b07836cf44 | 197 | // currently unsecured (sends over HTTP, not https) |
jksoft | 0:26b07836cf44 | 198 | // |
jksoft | 0:26b07836cf44 | 199 | bool |
jksoft | 0:26b07836cf44 | 200 | IFTTT::trigger(int triggerType) |
jksoft | 0:26b07836cf44 | 201 | { |
jksoft | 0:26b07836cf44 | 202 | int ret = 0; |
jksoft | 0:26b07836cf44 | 203 | switch(triggerType) { |
jksoft | 0:26b07836cf44 | 204 | case IFTTT_GET: |
jksoft | 0:26b07836cf44 | 205 | DBG("Sending Data as GET request"); |
jksoft | 0:26b07836cf44 | 206 | ret = get(); |
jksoft | 0:26b07836cf44 | 207 | break; |
jksoft | 0:26b07836cf44 | 208 | case IFTTT_POST: |
jksoft | 0:26b07836cf44 | 209 | DBG("Sending Data as POST request"); |
jksoft | 0:26b07836cf44 | 210 | ret = post(); |
jksoft | 0:26b07836cf44 | 211 | break; |
jksoft | 0:26b07836cf44 | 212 | |
jksoft | 0:26b07836cf44 | 213 | default: |
jksoft | 0:26b07836cf44 | 214 | WARN("Invalid type, defaulting to sending data as POST request"); |
jksoft | 0:26b07836cf44 | 215 | ret = post(); |
jksoft | 0:26b07836cf44 | 216 | break; |
jksoft | 0:26b07836cf44 | 217 | } |
jksoft | 0:26b07836cf44 | 218 | DBG("Sending Data return code : %d",ret); |
jksoft | 0:26b07836cf44 | 219 | if(ret){ |
jksoft | 0:26b07836cf44 | 220 | INFO("Successfully triggered event: '%s' with v1='%s', v2='%s', v3='%s' !",eventName,v1,v2,v3); |
jksoft | 0:26b07836cf44 | 221 | } |
jksoft | 0:26b07836cf44 | 222 | return ret; |
jksoft | 0:26b07836cf44 | 223 | } |