Twitter Coffee Maker

Dependencies:   4DGL-uLCD-SE EthernetInterface HTTPClientAuthAndPathExtension mbed-rtos mbed

Committer:
tlisowski3
Date:
Wed Apr 23 18:39:34 2014 +0000
Revision:
0:fe8909182706
Final version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tlisowski3 0:fe8909182706 1 #include "mbed.h"
tlisowski3 0:fe8909182706 2 #include "rtos.h"
tlisowski3 0:fe8909182706 3 #include "EthernetInterface.h"
tlisowski3 0:fe8909182706 4 #include "HTTPClient.h"
tlisowski3 0:fe8909182706 5 #include "uLCD_4DGL.h"
tlisowski3 0:fe8909182706 6 #include <string>
tlisowski3 0:fe8909182706 7 #define TWOCUPS ((2*60)+19) //TIME to brew two cups (seconds)
tlisowski3 0:fe8909182706 8 #define FOURCUPS ((4*60)+7) //""
tlisowski3 0:fe8909182706 9 #define SIXCUPS ((5*60)+56) //""
tlisowski3 0:fe8909182706 10 #define POSTURL "http://143.215.102.83:8080/1.1/statuses/update.json" //URL TO POST NEW STATUS
tlisowski3 0:fe8909182706 11 #define GETURL "http://143.215.102.83:8080/1.1/statuses/mentions_timeline.json?count=1" //URL TO GET DATA
tlisowski3 0:fe8909182706 12 #define REQUESTINTRVL 60 //Interval to make get requests
tlisowski3 0:fe8909182706 13
tlisowski3 0:fe8909182706 14
tlisowski3 0:fe8909182706 15 void clientCheck();
tlisowski3 0:fe8909182706 16 string checkCupTweet(string wholeTweet);
tlisowski3 0:fe8909182706 17 void postTweet(string tweet);
tlisowski3 0:fe8909182706 18 string getField(int startIndex,int startLength);
tlisowski3 0:fe8909182706 19 void checkReady();
tlisowski3 0:fe8909182706 20 void brew();
tlisowski3 0:fe8909182706 21
tlisowski3 0:fe8909182706 22 DigitalIn ready(p5); //Ready pin
tlisowski3 0:fe8909182706 23 DigitalOut coffeeTurnOn(p6); //Coffee Turn on pin
tlisowski3 0:fe8909182706 24 EthernetInterface eth;
tlisowski3 0:fe8909182706 25 HTTPClient client;
tlisowski3 0:fe8909182706 26 uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
tlisowski3 0:fe8909182706 27 char rawTweetInfo[8192];
tlisowski3 0:fe8909182706 28 string tweetInfo; //response from twitter
tlisowski3 0:fe8909182706 29 string previousID; //ID of preivously read tweet
tlisowski3 0:fe8909182706 30 string currentID; //ID of newest read tweet
tlisowski3 0:fe8909182706 31 string tweeter; //twitter handle of tweeter
tlisowski3 0:fe8909182706 32 string numCups; //Number of cups
tlisowski3 0:fe8909182706 33 int state; //STATE MACHINE CONTROLLING PROCESS
tlisowski3 0:fe8909182706 34
tlisowski3 0:fe8909182706 35 int main() {
tlisowski3 0:fe8909182706 36 state=5;
tlisowski3 0:fe8909182706 37 ready.mode(PullUp);
tlisowski3 0:fe8909182706 38 //Initialize Connection and get IP address
tlisowski3 0:fe8909182706 39 eth.init();
tlisowski3 0:fe8909182706 40 eth.connect();
tlisowski3 0:fe8909182706 41 //Get inital information for current ID field
tlisowski3 0:fe8909182706 42 clientCheck();
tlisowski3 0:fe8909182706 43 uLCD.cls();
tlisowski3 0:fe8909182706 44 uLCD.printf("Machine Needs coffee and water");
tlisowski3 0:fe8909182706 45 wait(5.0);
tlisowski3 0:fe8909182706 46 //End initalization
tlisowski3 0:fe8909182706 47 while(1){
tlisowski3 0:fe8909182706 48 //Check if the machine is ready to brew (accepts input from pushbutton)
tlisowski3 0:fe8909182706 49 checkReady();
tlisowski3 0:fe8909182706 50 //Check if new tweet has been sent and if its proper format
tlisowski3 0:fe8909182706 51 clientCheck();
tlisowski3 0:fe8909182706 52 //See if brew process should start
tlisowski3 0:fe8909182706 53 brew(); //END
tlisowski3 0:fe8909182706 54 }
tlisowski3 0:fe8909182706 55 }
tlisowski3 0:fe8909182706 56
tlisowski3 0:fe8909182706 57
tlisowski3 0:fe8909182706 58 void checkReady() {
tlisowski3 0:fe8909182706 59 int loopVar=1000000000/2;
tlisowski3 0:fe8909182706 60 while(loopVar>0){
tlisowski3 0:fe8909182706 61 if(state>0) break;
tlisowski3 0:fe8909182706 62 else{
tlisowski3 0:fe8909182706 63 if(!(ready)){
tlisowski3 0:fe8909182706 64 state=1;
tlisowski3 0:fe8909182706 65 uLCD.cls();
tlisowski3 0:fe8909182706 66 uLCD.printf("Machine Ready, waiting for Command");
tlisowski3 0:fe8909182706 67 }
tlisowski3 0:fe8909182706 68 }
tlisowski3 0:fe8909182706 69 loopVar=loopVar-1;
tlisowski3 0:fe8909182706 70 }
tlisowski3 0:fe8909182706 71 }
tlisowski3 0:fe8909182706 72
tlisowski3 0:fe8909182706 73 /*
tlisowski3 0:fe8909182706 74 Post a tweet to twitter using the coffee machines handle.
tlisowski3 0:fe8909182706 75 This allows us to notify the tweeter of our course of action.
tlisowski3 0:fe8909182706 76
tlisowski3 0:fe8909182706 77 @param tweet- the tweet you are sending to the user
tlisowski3 0:fe8909182706 78
tlisowski3 0:fe8909182706 79 */
tlisowski3 0:fe8909182706 80 void postTweet(string tweet){
tlisowski3 0:fe8909182706 81 char str[512];
tlisowski3 0:fe8909182706 82 int i;
tlisowski3 0:fe8909182706 83 HTTPText inText(str, 512);
tlisowski3 0:fe8909182706 84 HTTPMap mapp;
tlisowski3 0:fe8909182706 85 mapp.put("status",tweet.c_str());
tlisowski3 0:fe8909182706 86 for(i=0;i<2;i++){//TRY POSTING IT 3 TIMES OTHERWISE LET IT GO
tlisowski3 0:fe8909182706 87 int ret=client.post(POSTURL, mapp, &inText);
tlisowski3 0:fe8909182706 88 if (!ret)
tlisowski3 0:fe8909182706 89 {
tlisowski3 0:fe8909182706 90 uLCD.printf("Executed POST successfully - read characters\n");
tlisowski3 0:fe8909182706 91 break;
tlisowski3 0:fe8909182706 92 }
tlisowski3 0:fe8909182706 93 else
tlisowski3 0:fe8909182706 94 {
tlisowski3 0:fe8909182706 95 uLCD.printf("Error Posting Data\n");
tlisowski3 0:fe8909182706 96 tweet+=".";
tlisowski3 0:fe8909182706 97 mapp.clear();
tlisowski3 0:fe8909182706 98 mapp.put("status",tweet.c_str());
tlisowski3 0:fe8909182706 99 wait(2.0);
tlisowski3 0:fe8909182706 100 continue;
tlisowski3 0:fe8909182706 101 }
tlisowski3 0:fe8909182706 102 }
tlisowski3 0:fe8909182706 103 }
tlisowski3 0:fe8909182706 104 /*
tlisowski3 0:fe8909182706 105 Gets the value of a field sent back from twitter through an HTTP get request.
tlisowski3 0:fe8909182706 106 The data is in JSON format and can be parsed accordingly.
tlisowski3 0:fe8909182706 107
tlisowski3 0:fe8909182706 108 @param startIndex- starting index in response (of header)
tlisowski3 0:fe8909182706 109 @param startLength- the length of the header (in characters)
tlisowski3 0:fe8909182706 110
tlisowski3 0:fe8909182706 111 return
tlisowski3 0:fe8909182706 112 finalResult- the value of the field as a string
tlisowski3 0:fe8909182706 113
tlisowski3 0:fe8909182706 114 */
tlisowski3 0:fe8909182706 115 string getField(int startIndex,int startLength){
tlisowski3 0:fe8909182706 116 int start=startIndex+startLength+1; //should be first letter
tlisowski3 0:fe8909182706 117 char curChar=tweetInfo.at(start); //first letter
tlisowski3 0:fe8909182706 118 string finalResult="";
tlisowski3 0:fe8909182706 119 while(curChar !='\"'){
tlisowski3 0:fe8909182706 120 finalResult+=curChar;
tlisowski3 0:fe8909182706 121 start=start+1;
tlisowski3 0:fe8909182706 122 curChar=tweetInfo.at(start);
tlisowski3 0:fe8909182706 123 }
tlisowski3 0:fe8909182706 124 return finalResult;
tlisowski3 0:fe8909182706 125 }
tlisowski3 0:fe8909182706 126
tlisowski3 0:fe8909182706 127 /*
tlisowski3 0:fe8909182706 128 Gets the newest tweet from the coffee Machines twitter feed.
tlisowski3 0:fe8909182706 129 Responds to the tweet based on the current state of the coffee machine
tlisowski3 0:fe8909182706 130 and whether the tweet was in the proper format or not.
tlisowski3 0:fe8909182706 131 */
tlisowski3 0:fe8909182706 132 void clientCheck(){
tlisowski3 0:fe8909182706 133 int ret = client.get(GETURL,rawTweetInfo,4096); //Do HTTP GET REQUEST
tlisowski3 0:fe8909182706 134 double rqstInt=REQUESTINTRVL;
tlisowski3 0:fe8909182706 135 if (ret) { //IF Request failed
tlisowski3 0:fe8909182706 136 uLCD.cls();
tlisowski3 0:fe8909182706 137 uLCD.printf("FAIL GETTING DATA\n");
tlisowski3 0:fe8909182706 138 uLCD.printf("ERROR= %d\n",ret);
tlisowski3 0:fe8909182706 139 uLCD.printf("Error - ret = %d - HTTP return code = %d\n", ret, client.getHTTPResponseCode());
tlisowski3 0:fe8909182706 140 wait(rqstInt);
tlisowski3 0:fe8909182706 141 return;
tlisowski3 0:fe8909182706 142 }
tlisowski3 0:fe8909182706 143 tweetInfo=rawTweetInfo;
tlisowski3 0:fe8909182706 144 string tweeterStart="\"screen_name\":"; //Header in request for twitter handle
tlisowski3 0:fe8909182706 145 string numCupsStart="\"text\":"; //Header in request for tweet
tlisowski3 0:fe8909182706 146 string idStart="\"id_str\":"; //Header in request for the unique ID with every tweet
tlisowski3 0:fe8909182706 147 int indexID=tweetInfo.find(idStart,0);
tlisowski3 0:fe8909182706 148 int indexTweeter=tweetInfo.find(tweeterStart,0);
tlisowski3 0:fe8909182706 149 int indexNumCups=tweetInfo.find(numCupsStart,0);
tlisowski3 0:fe8909182706 150 int tweeterLength=tweeterStart.length();
tlisowski3 0:fe8909182706 151 int cupsLength=numCupsStart.length();
tlisowski3 0:fe8909182706 152 int idLength=idStart.length();
tlisowski3 0:fe8909182706 153 //Get the idString
tlisowski3 0:fe8909182706 154 string tempID=getField(indexID,idLength);
tlisowski3 0:fe8909182706 155 if(strcmp(tempID.c_str(),currentID.c_str())==0);//do nothing, no new tweet
tlisowski3 0:fe8909182706 156 else{//got a new tweet
tlisowski3 0:fe8909182706 157 previousID=currentID;
tlisowski3 0:fe8909182706 158 currentID=tempID;
tlisowski3 0:fe8909182706 159 string tempTweeter=getField(indexTweeter,tweeterLength); //NEED TO ADD @ Symbol
tlisowski3 0:fe8909182706 160 tempTweeter=tempTweeter.insert(0,"@"); //Insert at symbol
tlisowski3 0:fe8909182706 161 if(state==2){//already brewing
tlisowski3 0:fe8909182706 162 tempTweeter+=" Currently brewing try again later";
tlisowski3 0:fe8909182706 163 postTweet(tempTweeter);
tlisowski3 0:fe8909182706 164 }
tlisowski3 0:fe8909182706 165 else if(state==0){//Not ready so notify the machine is not ready
tlisowski3 0:fe8909182706 166 tempTweeter+=" Coffee Machine not Ready. Needs Water and Grinds";
tlisowski3 0:fe8909182706 167 postTweet(tempTweeter);
tlisowski3 0:fe8909182706 168 }
tlisowski3 0:fe8909182706 169 else if(state==5) state=0; //Initialization state
tlisowski3 0:fe8909182706 170 else{
tlisowski3 0:fe8909182706 171 //Check if its a valid cup tweet
tlisowski3 0:fe8909182706 172 //Get the whole tweet
tlisowski3 0:fe8909182706 173 string wholeTweet=getField(indexNumCups,cupsLength);
tlisowski3 0:fe8909182706 174 string tempCup=checkCupTweet(wholeTweet);
tlisowski3 0:fe8909182706 175 if(strcmp(tempCup.c_str(),"inv")==0){ //Invalid format. Notify user
tlisowski3 0:fe8909182706 176 tempTweeter+=" Invalid Format. Use <handle> <numcups> cups";
tlisowski3 0:fe8909182706 177 postTweet(tempTweeter);
tlisowski3 0:fe8909182706 178 }
tlisowski3 0:fe8909182706 179 else{//ALL GOOD SET EVERYTHING
tlisowski3 0:fe8909182706 180 numCups=tempCup;
tlisowski3 0:fe8909182706 181 tweeter=tempTweeter;
tlisowski3 0:fe8909182706 182 state=3;
tlisowski3 0:fe8909182706 183 }
tlisowski3 0:fe8909182706 184 }
tlisowski3 0:fe8909182706 185 }
tlisowski3 0:fe8909182706 186 wait(rqstInt);
tlisowski3 0:fe8909182706 187 }
tlisowski3 0:fe8909182706 188 /*
tlisowski3 0:fe8909182706 189 Extracts the number of cups specified in a tweet to the coffee maker.
tlisowski3 0:fe8909182706 190 If no valid number, sets the cups field as inv.
tlisowski3 0:fe8909182706 191
tlisowski3 0:fe8909182706 192 @param wholeTweet- tweet that a user sent to the coffee machine
tlisowski3 0:fe8909182706 193
tlisowski3 0:fe8909182706 194 return
tlisowski3 0:fe8909182706 195 result- a string with either the number of cups in the tweet or inv
tlisowski3 0:fe8909182706 196
tlisowski3 0:fe8909182706 197 */
tlisowski3 0:fe8909182706 198 string checkCupTweet(string wholeTweet){
tlisowski3 0:fe8909182706 199 string subTweet;
tlisowski3 0:fe8909182706 200 string result;
tlisowski3 0:fe8909182706 201 char curChar=wholeTweet.at(0);
tlisowski3 0:fe8909182706 202 if(curChar!='@'){
tlisowski3 0:fe8909182706 203 result="inv";
tlisowski3 0:fe8909182706 204 }
tlisowski3 0:fe8909182706 205 else{
tlisowski3 0:fe8909182706 206 while(curChar!=' '){
tlisowski3 0:fe8909182706 207 wholeTweet.erase(0,1);
tlisowski3 0:fe8909182706 208 curChar=wholeTweet.at(0);
tlisowski3 0:fe8909182706 209 }
tlisowski3 0:fe8909182706 210 subTweet=wholeTweet;
tlisowski3 0:fe8909182706 211 if(subTweet.find_first_of("2",0) != string::npos){
tlisowski3 0:fe8909182706 212 result="2";
tlisowski3 0:fe8909182706 213 }
tlisowski3 0:fe8909182706 214 else if(subTweet.find_first_of("4",0) != string::npos){
tlisowski3 0:fe8909182706 215 result="4";
tlisowski3 0:fe8909182706 216 }
tlisowski3 0:fe8909182706 217 else if(subTweet.find_first_of("6",0) != string::npos){
tlisowski3 0:fe8909182706 218 result="6";
tlisowski3 0:fe8909182706 219 }
tlisowski3 0:fe8909182706 220 else{
tlisowski3 0:fe8909182706 221 result="inv";
tlisowski3 0:fe8909182706 222 }
tlisowski3 0:fe8909182706 223 }
tlisowski3 0:fe8909182706 224 return result;
tlisowski3 0:fe8909182706 225 }
tlisowski3 0:fe8909182706 226
tlisowski3 0:fe8909182706 227
tlisowski3 0:fe8909182706 228
tlisowski3 0:fe8909182706 229 /*
tlisowski3 0:fe8909182706 230 Handles the brewing process. Checks if the state is set to the proper value (3)
tlisowski3 0:fe8909182706 231 and then goes through the brewing process. If it is not the proper state, simply
tlisowski3 0:fe8909182706 232 exits the function.
tlisowski3 0:fe8909182706 233 */
tlisowski3 0:fe8909182706 234 void brew(){
tlisowski3 0:fe8909182706 235 double rqstInt=REQUESTINTRVL;
tlisowski3 0:fe8909182706 236 if(state==3){//DO THE BREW
tlisowski3 0:fe8909182706 237 uLCD.cls();
tlisowski3 0:fe8909182706 238 uLCD.printf("BREWING");
tlisowski3 0:fe8909182706 239 int numTimes;
tlisowski3 0:fe8909182706 240 int i;
tlisowski3 0:fe8909182706 241 double remainder;
tlisowski3 0:fe8909182706 242 int timeToBrew;
tlisowski3 0:fe8909182706 243 state=2;
tlisowski3 0:fe8909182706 244 string sendTweet=tweeter;
tlisowski3 0:fe8909182706 245 sendTweet+=" Starting to brew!";
tlisowski3 0:fe8909182706 246 postTweet(sendTweet);
tlisowski3 0:fe8909182706 247 coffeeTurnOn=1;
tlisowski3 0:fe8909182706 248 if(strcmp(numCups.c_str(),"2")==0){
tlisowski3 0:fe8909182706 249 timeToBrew=TWOCUPS;
tlisowski3 0:fe8909182706 250 numTimes=timeToBrew/rqstInt;
tlisowski3 0:fe8909182706 251 remainder= timeToBrew % ((int)rqstInt);
tlisowski3 0:fe8909182706 252 for(i=0;i<numTimes;i++){
tlisowski3 0:fe8909182706 253 clientCheck();
tlisowski3 0:fe8909182706 254 }
tlisowski3 0:fe8909182706 255 wait(remainder);
tlisowski3 0:fe8909182706 256 }
tlisowski3 0:fe8909182706 257 else if(strcmp(numCups.c_str(),"4")==0){
tlisowski3 0:fe8909182706 258 numTimes=FOURCUPS/rqstInt;
tlisowski3 0:fe8909182706 259 remainder= FOURCUPS % ((int)rqstInt);
tlisowski3 0:fe8909182706 260 for(i=0;i<numTimes;i++){
tlisowski3 0:fe8909182706 261 clientCheck();
tlisowski3 0:fe8909182706 262 }
tlisowski3 0:fe8909182706 263 wait(remainder);
tlisowski3 0:fe8909182706 264 }
tlisowski3 0:fe8909182706 265 else if(strcmp(numCups.c_str(),"6")==0){
tlisowski3 0:fe8909182706 266 numTimes=SIXCUPS/rqstInt;
tlisowski3 0:fe8909182706 267 remainder= SIXCUPS % ((int)rqstInt);
tlisowski3 0:fe8909182706 268 for(i=0;i<numTimes;i++){
tlisowski3 0:fe8909182706 269 clientCheck();
tlisowski3 0:fe8909182706 270 }
tlisowski3 0:fe8909182706 271 wait(remainder);
tlisowski3 0:fe8909182706 272 }
tlisowski3 0:fe8909182706 273 sendTweet=tweeter;
tlisowski3 0:fe8909182706 274 sendTweet+=" done brewing. Enjoy!";
tlisowski3 0:fe8909182706 275 postTweet(sendTweet);
tlisowski3 0:fe8909182706 276 coffeeTurnOn=0;
tlisowski3 0:fe8909182706 277 state=0;
tlisowski3 0:fe8909182706 278 }
tlisowski3 0:fe8909182706 279 else;
tlisowski3 0:fe8909182706 280 }