Twitter Coffee Maker
Dependencies: 4DGL-uLCD-SE EthernetInterface HTTPClientAuthAndPathExtension mbed-rtos mbed
main.cpp
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 #include "EthernetInterface.h" 00004 #include "HTTPClient.h" 00005 #include "uLCD_4DGL.h" 00006 #include <string> 00007 #define TWOCUPS ((2*60)+19) //TIME to brew two cups (seconds) 00008 #define FOURCUPS ((4*60)+7) //"" 00009 #define SIXCUPS ((5*60)+56) //"" 00010 #define POSTURL "http://143.215.102.83:8080/1.1/statuses/update.json" //URL TO POST NEW STATUS 00011 #define GETURL "http://143.215.102.83:8080/1.1/statuses/mentions_timeline.json?count=1" //URL TO GET DATA 00012 #define REQUESTINTRVL 60 //Interval to make get requests 00013 00014 00015 void clientCheck(); 00016 string checkCupTweet(string wholeTweet); 00017 void postTweet(string tweet); 00018 string getField(int startIndex,int startLength); 00019 void checkReady(); 00020 void brew(); 00021 00022 DigitalIn ready(p5); //Ready pin 00023 DigitalOut coffeeTurnOn(p6); //Coffee Turn on pin 00024 EthernetInterface eth; 00025 HTTPClient client; 00026 uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin; 00027 char rawTweetInfo[8192]; 00028 string tweetInfo; //response from twitter 00029 string previousID; //ID of preivously read tweet 00030 string currentID; //ID of newest read tweet 00031 string tweeter; //twitter handle of tweeter 00032 string numCups; //Number of cups 00033 int state; //STATE MACHINE CONTROLLING PROCESS 00034 00035 int main() { 00036 state=5; 00037 ready.mode(PullUp); 00038 //Initialize Connection and get IP address 00039 eth.init(); 00040 eth.connect(); 00041 //Get inital information for current ID field 00042 clientCheck(); 00043 uLCD.cls(); 00044 uLCD.printf("Machine Needs coffee and water"); 00045 wait(5.0); 00046 //End initalization 00047 while(1){ 00048 //Check if the machine is ready to brew (accepts input from pushbutton) 00049 checkReady(); 00050 //Check if new tweet has been sent and if its proper format 00051 clientCheck(); 00052 //See if brew process should start 00053 brew(); //END 00054 } 00055 } 00056 00057 00058 void checkReady() { 00059 int loopVar=1000000000/2; 00060 while(loopVar>0){ 00061 if(state>0) break; 00062 else{ 00063 if(!(ready)){ 00064 state=1; 00065 uLCD.cls(); 00066 uLCD.printf("Machine Ready, waiting for Command"); 00067 } 00068 } 00069 loopVar=loopVar-1; 00070 } 00071 } 00072 00073 /* 00074 Post a tweet to twitter using the coffee machines handle. 00075 This allows us to notify the tweeter of our course of action. 00076 00077 @param tweet- the tweet you are sending to the user 00078 00079 */ 00080 void postTweet(string tweet){ 00081 char str[512]; 00082 int i; 00083 HTTPText inText(str, 512); 00084 HTTPMap mapp; 00085 mapp.put("status",tweet.c_str()); 00086 for(i=0;i<2;i++){//TRY POSTING IT 3 TIMES OTHERWISE LET IT GO 00087 int ret=client.post(POSTURL, mapp, &inText); 00088 if (!ret) 00089 { 00090 uLCD.printf("Executed POST successfully - read characters\n"); 00091 break; 00092 } 00093 else 00094 { 00095 uLCD.printf("Error Posting Data\n"); 00096 tweet+="."; 00097 mapp.clear(); 00098 mapp.put("status",tweet.c_str()); 00099 wait(2.0); 00100 continue; 00101 } 00102 } 00103 } 00104 /* 00105 Gets the value of a field sent back from twitter through an HTTP get request. 00106 The data is in JSON format and can be parsed accordingly. 00107 00108 @param startIndex- starting index in response (of header) 00109 @param startLength- the length of the header (in characters) 00110 00111 return 00112 finalResult- the value of the field as a string 00113 00114 */ 00115 string getField(int startIndex,int startLength){ 00116 int start=startIndex+startLength+1; //should be first letter 00117 char curChar=tweetInfo.at(start); //first letter 00118 string finalResult=""; 00119 while(curChar !='\"'){ 00120 finalResult+=curChar; 00121 start=start+1; 00122 curChar=tweetInfo.at(start); 00123 } 00124 return finalResult; 00125 } 00126 00127 /* 00128 Gets the newest tweet from the coffee Machines twitter feed. 00129 Responds to the tweet based on the current state of the coffee machine 00130 and whether the tweet was in the proper format or not. 00131 */ 00132 void clientCheck(){ 00133 int ret = client.get(GETURL,rawTweetInfo,4096); //Do HTTP GET REQUEST 00134 double rqstInt=REQUESTINTRVL; 00135 if (ret) { //IF Request failed 00136 uLCD.cls(); 00137 uLCD.printf("FAIL GETTING DATA\n"); 00138 uLCD.printf("ERROR= %d\n",ret); 00139 uLCD.printf("Error - ret = %d - HTTP return code = %d\n", ret, client.getHTTPResponseCode()); 00140 wait(rqstInt); 00141 return; 00142 } 00143 tweetInfo=rawTweetInfo; 00144 string tweeterStart="\"screen_name\":"; //Header in request for twitter handle 00145 string numCupsStart="\"text\":"; //Header in request for tweet 00146 string idStart="\"id_str\":"; //Header in request for the unique ID with every tweet 00147 int indexID=tweetInfo.find(idStart,0); 00148 int indexTweeter=tweetInfo.find(tweeterStart,0); 00149 int indexNumCups=tweetInfo.find(numCupsStart,0); 00150 int tweeterLength=tweeterStart.length(); 00151 int cupsLength=numCupsStart.length(); 00152 int idLength=idStart.length(); 00153 //Get the idString 00154 string tempID=getField(indexID,idLength); 00155 if(strcmp(tempID.c_str(),currentID.c_str())==0);//do nothing, no new tweet 00156 else{//got a new tweet 00157 previousID=currentID; 00158 currentID=tempID; 00159 string tempTweeter=getField(indexTweeter,tweeterLength); //NEED TO ADD @ Symbol 00160 tempTweeter=tempTweeter.insert(0,"@"); //Insert at symbol 00161 if(state==2){//already brewing 00162 tempTweeter+=" Currently brewing try again later"; 00163 postTweet(tempTweeter); 00164 } 00165 else if(state==0){//Not ready so notify the machine is not ready 00166 tempTweeter+=" Coffee Machine not Ready. Needs Water and Grinds"; 00167 postTweet(tempTweeter); 00168 } 00169 else if(state==5) state=0; //Initialization state 00170 else{ 00171 //Check if its a valid cup tweet 00172 //Get the whole tweet 00173 string wholeTweet=getField(indexNumCups,cupsLength); 00174 string tempCup=checkCupTweet(wholeTweet); 00175 if(strcmp(tempCup.c_str(),"inv")==0){ //Invalid format. Notify user 00176 tempTweeter+=" Invalid Format. Use <handle> <numcups> cups"; 00177 postTweet(tempTweeter); 00178 } 00179 else{//ALL GOOD SET EVERYTHING 00180 numCups=tempCup; 00181 tweeter=tempTweeter; 00182 state=3; 00183 } 00184 } 00185 } 00186 wait(rqstInt); 00187 } 00188 /* 00189 Extracts the number of cups specified in a tweet to the coffee maker. 00190 If no valid number, sets the cups field as inv. 00191 00192 @param wholeTweet- tweet that a user sent to the coffee machine 00193 00194 return 00195 result- a string with either the number of cups in the tweet or inv 00196 00197 */ 00198 string checkCupTweet(string wholeTweet){ 00199 string subTweet; 00200 string result; 00201 char curChar=wholeTweet.at(0); 00202 if(curChar!='@'){ 00203 result="inv"; 00204 } 00205 else{ 00206 while(curChar!=' '){ 00207 wholeTweet.erase(0,1); 00208 curChar=wholeTweet.at(0); 00209 } 00210 subTweet=wholeTweet; 00211 if(subTweet.find_first_of("2",0) != string::npos){ 00212 result="2"; 00213 } 00214 else if(subTweet.find_first_of("4",0) != string::npos){ 00215 result="4"; 00216 } 00217 else if(subTweet.find_first_of("6",0) != string::npos){ 00218 result="6"; 00219 } 00220 else{ 00221 result="inv"; 00222 } 00223 } 00224 return result; 00225 } 00226 00227 00228 00229 /* 00230 Handles the brewing process. Checks if the state is set to the proper value (3) 00231 and then goes through the brewing process. If it is not the proper state, simply 00232 exits the function. 00233 */ 00234 void brew(){ 00235 double rqstInt=REQUESTINTRVL; 00236 if(state==3){//DO THE BREW 00237 uLCD.cls(); 00238 uLCD.printf("BREWING"); 00239 int numTimes; 00240 int i; 00241 double remainder; 00242 int timeToBrew; 00243 state=2; 00244 string sendTweet=tweeter; 00245 sendTweet+=" Starting to brew!"; 00246 postTweet(sendTweet); 00247 coffeeTurnOn=1; 00248 if(strcmp(numCups.c_str(),"2")==0){ 00249 timeToBrew=TWOCUPS; 00250 numTimes=timeToBrew/rqstInt; 00251 remainder= timeToBrew % ((int)rqstInt); 00252 for(i=0;i<numTimes;i++){ 00253 clientCheck(); 00254 } 00255 wait(remainder); 00256 } 00257 else if(strcmp(numCups.c_str(),"4")==0){ 00258 numTimes=FOURCUPS/rqstInt; 00259 remainder= FOURCUPS % ((int)rqstInt); 00260 for(i=0;i<numTimes;i++){ 00261 clientCheck(); 00262 } 00263 wait(remainder); 00264 } 00265 else if(strcmp(numCups.c_str(),"6")==0){ 00266 numTimes=SIXCUPS/rqstInt; 00267 remainder= SIXCUPS % ((int)rqstInt); 00268 for(i=0;i<numTimes;i++){ 00269 clientCheck(); 00270 } 00271 wait(remainder); 00272 } 00273 sendTweet=tweeter; 00274 sendTweet+=" done brewing. Enjoy!"; 00275 postTweet(sendTweet); 00276 coffeeTurnOn=0; 00277 state=0; 00278 } 00279 else; 00280 }
Generated on Thu Jul 14 2022 08:45:30 by 1.7.2