Twitter Coffee Maker

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

Files at this revision

API Documentation at this revision

Comitter:
tlisowski3
Date:
Wed Apr 23 18:39:34 2014 +0000
Commit message:
Final version

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
EthernetInterface.lib Show annotated file Show diff for this revision Revisions of this file
HTTPClientAuthAndPathExtension.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-rtos.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r fe8909182706 4DGL-uLCD-SE.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/4DGL-uLCD-SE.lib	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/4180_1/code/4DGL-uLCD-SE/#e39a44de229a
diff -r 000000000000 -r fe8909182706 EthernetInterface.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EthernetInterface.lib	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/EthernetInterface/#6a67d2bddc7c
diff -r 000000000000 -r fe8909182706 HTTPClientAuthAndPathExtension.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPClientAuthAndPathExtension.lib	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/tlisowski3/code/HTTPClientAuthAndPathExtension/#da79dd7e9df2
diff -r 000000000000 -r fe8909182706 main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,280 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "EthernetInterface.h"
+#include "HTTPClient.h"
+#include "uLCD_4DGL.h"
+#include <string>
+#define TWOCUPS ((2*60)+19) //TIME to brew two cups (seconds)
+#define FOURCUPS ((4*60)+7) //""
+#define SIXCUPS ((5*60)+56) //""
+#define POSTURL "http://143.215.102.83:8080/1.1/statuses/update.json" //URL TO POST NEW STATUS
+#define GETURL "http://143.215.102.83:8080/1.1/statuses/mentions_timeline.json?count=1" //URL TO GET DATA
+#define REQUESTINTRVL 60  //Interval to make get requests
+
+
+void clientCheck();
+string checkCupTweet(string wholeTweet);
+void postTweet(string tweet);
+string getField(int startIndex,int startLength);
+void checkReady();
+void brew();
+
+DigitalIn ready(p5); //Ready pin
+DigitalOut coffeeTurnOn(p6); //Coffee Turn on pin
+EthernetInterface eth;
+HTTPClient client;
+uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
+char rawTweetInfo[8192];
+string tweetInfo; //response from twitter
+string previousID; //ID of preivously read tweet
+string currentID; //ID of newest read tweet
+string tweeter; //twitter handle of tweeter
+string numCups; //Number of cups 
+int state; //STATE MACHINE CONTROLLING PROCESS
+
+int main() {
+    state=5;
+    ready.mode(PullUp);
+    //Initialize Connection and get IP address
+    eth.init();
+    eth.connect();
+    //Get inital information for current ID field
+    clientCheck();
+    uLCD.cls();
+    uLCD.printf("Machine Needs coffee and water");
+    wait(5.0);
+    //End initalization
+    while(1){
+        //Check if the machine is ready to brew (accepts input from pushbutton)
+        checkReady();
+        //Check if new tweet has been sent and if its proper format
+        clientCheck();
+        //See if brew process should start
+        brew(); //END 
+    }  
+}
+
+
+void checkReady() {
+    int loopVar=1000000000/2;
+    while(loopVar>0){
+        if(state>0) break;
+        else{
+            if(!(ready)){
+                state=1;
+                uLCD.cls();
+                uLCD.printf("Machine Ready, waiting for Command");
+            }
+        }
+        loopVar=loopVar-1;
+    }
+}
+
+/*
+    Post a tweet to twitter using the coffee machines handle.
+    This allows us to notify the tweeter of our course of action.
+    
+    @param tweet- the tweet you are sending to the user
+
+*/
+void postTweet(string tweet){
+        char str[512];
+        int i;
+        HTTPText inText(str, 512);
+        HTTPMap mapp;
+        mapp.put("status",tweet.c_str());
+        for(i=0;i<2;i++){//TRY POSTING IT 3 TIMES OTHERWISE LET IT GO
+            int ret=client.post(POSTURL, mapp, &inText);
+            if (!ret)
+            {
+                uLCD.printf("Executed POST successfully - read characters\n");
+                break;
+            }
+            else
+            {
+                uLCD.printf("Error Posting Data\n");
+                tweet+=".";
+                mapp.clear();
+                mapp.put("status",tweet.c_str());
+                wait(2.0);
+                continue;
+            }
+        }
+}
+/*
+    Gets the value of a field sent back from twitter through an HTTP get request.
+    The data is in JSON format and can be parsed accordingly. 
+    
+    @param startIndex- starting index in response (of header)
+    @param startLength- the length of the header (in characters)
+    
+    return
+    finalResult- the value of the field as a string
+    
+*/
+string getField(int startIndex,int startLength){
+    int start=startIndex+startLength+1; //should be first letter
+    char curChar=tweetInfo.at(start); //first letter
+    string finalResult=""; 
+    while(curChar !='\"'){
+        finalResult+=curChar;
+        start=start+1;
+        curChar=tweetInfo.at(start);
+    }
+    return finalResult;
+}
+
+/*
+    Gets the newest tweet from the coffee Machines twitter feed.
+    Responds to the tweet based on the current state of the coffee machine
+    and whether the tweet was in the proper format or not.
+*/
+void clientCheck(){
+    int ret = client.get(GETURL,rawTweetInfo,4096); //Do HTTP GET REQUEST
+    double rqstInt=REQUESTINTRVL;
+    if (ret) { //IF Request failed
+        uLCD.cls();
+        uLCD.printf("FAIL GETTING DATA\n");
+        uLCD.printf("ERROR= %d\n",ret);
+        uLCD.printf("Error - ret = %d - HTTP return code = %d\n", ret, client.getHTTPResponseCode());
+        wait(rqstInt);
+        return;
+    }
+    tweetInfo=rawTweetInfo;
+    string tweeterStart="\"screen_name\":"; //Header in request for twitter handle
+    string numCupsStart="\"text\":"; //Header in request for tweet
+    string idStart="\"id_str\":"; //Header in request for the unique ID with every tweet
+    int indexID=tweetInfo.find(idStart,0);
+    int indexTweeter=tweetInfo.find(tweeterStart,0);
+    int indexNumCups=tweetInfo.find(numCupsStart,0);
+    int tweeterLength=tweeterStart.length();
+    int cupsLength=numCupsStart.length();
+    int idLength=idStart.length();     
+    //Get the idString
+    string tempID=getField(indexID,idLength);
+    if(strcmp(tempID.c_str(),currentID.c_str())==0);//do nothing, no new tweet
+    else{//got a new tweet
+        previousID=currentID;
+        currentID=tempID;
+        string tempTweeter=getField(indexTweeter,tweeterLength); //NEED TO ADD @ Symbol
+        tempTweeter=tempTweeter.insert(0,"@"); //Insert at symbol
+        if(state==2){//already brewing
+            tempTweeter+=" Currently brewing try again later";
+            postTweet(tempTweeter);
+        }
+        else if(state==0){//Not ready so notify the machine is not ready
+            tempTweeter+=" Coffee Machine not Ready. Needs Water and Grinds";
+            postTweet(tempTweeter);
+        }
+        else if(state==5) state=0; //Initialization state
+        else{
+            //Check if its a valid cup tweet
+            //Get the whole tweet
+            string wholeTweet=getField(indexNumCups,cupsLength);
+            string tempCup=checkCupTweet(wholeTweet);
+            if(strcmp(tempCup.c_str(),"inv")==0){ //Invalid format. Notify user
+                tempTweeter+=" Invalid Format. Use <handle> <numcups> cups";
+                postTweet(tempTweeter);
+            }
+            else{//ALL GOOD SET EVERYTHING
+                numCups=tempCup;
+                tweeter=tempTweeter;
+                state=3;
+            }
+        }
+    }
+    wait(rqstInt); 
+}
+/*
+    Extracts the number of cups specified in a tweet to the coffee maker.
+    If no valid number, sets the cups field as inv.
+    
+    @param wholeTweet- tweet that a user sent to the coffee machine
+    
+    return
+    result- a string with either the number of cups in the tweet or inv
+
+*/
+string checkCupTweet(string wholeTweet){
+    string subTweet;
+    string result;
+    char curChar=wholeTweet.at(0);
+    if(curChar!='@'){
+        result="inv";
+    }
+    else{
+        while(curChar!=' '){
+            wholeTweet.erase(0,1);
+            curChar=wholeTweet.at(0);   
+        }
+        subTweet=wholeTweet;
+        if(subTweet.find_first_of("2",0) != string::npos){
+            result="2";    
+        }
+        else if(subTweet.find_first_of("4",0) != string::npos){
+            result="4";
+        }
+        else if(subTweet.find_first_of("6",0) != string::npos){
+            result="6";
+        }
+        else{
+            result="inv";
+        }
+    }
+    return result;    
+}
+
+
+
+/*
+    Handles the brewing process. Checks if the state is set to the proper value (3)
+    and then goes through the brewing process. If it is not the proper state, simply
+    exits the function.
+*/
+void brew(){
+    double rqstInt=REQUESTINTRVL;
+    if(state==3){//DO THE BREW
+        uLCD.cls();
+        uLCD.printf("BREWING");
+        int numTimes;
+        int i;
+        double remainder;
+        int timeToBrew;
+        state=2;
+        string sendTweet=tweeter;
+        sendTweet+=" Starting to brew!";
+        postTweet(sendTweet);
+        coffeeTurnOn=1;
+        if(strcmp(numCups.c_str(),"2")==0){
+            timeToBrew=TWOCUPS;
+            numTimes=timeToBrew/rqstInt;
+            remainder= timeToBrew % ((int)rqstInt);
+            for(i=0;i<numTimes;i++){
+                clientCheck();
+            }
+            wait(remainder);
+        }
+        else if(strcmp(numCups.c_str(),"4")==0){
+            numTimes=FOURCUPS/rqstInt;
+            remainder= FOURCUPS % ((int)rqstInt);
+            for(i=0;i<numTimes;i++){
+                clientCheck();
+            }
+            wait(remainder);
+        }
+        else if(strcmp(numCups.c_str(),"6")==0){
+            numTimes=SIXCUPS/rqstInt;
+            remainder= SIXCUPS % ((int)rqstInt);  
+            for(i=0;i<numTimes;i++){
+                clientCheck();
+            }
+            wait(remainder);  
+        }
+        sendTweet=tweeter;
+        sendTweet+=" done brewing. Enjoy!";
+        postTweet(sendTweet);
+        coffeeTurnOn=0;
+        state=0;  
+    }
+    else;     
+}  
\ No newline at end of file
diff -r 000000000000 -r fe8909182706 mbed-rtos.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-rtos.lib	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed-rtos/#4ef72665e2c8
diff -r 000000000000 -r fe8909182706 mbed.bld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Wed Apr 23 18:39:34 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/6473597d706e
\ No newline at end of file