adfa
Dependencies: 4DGL-uLCD-SE NetServices mbed spxml
Fork of weather by
main.cpp@7:92cbee5144d7, 2016-04-29 (annotated)
- Committer:
- agamemaker
- Date:
- Fri Apr 29 05:53:09 2016 +0000
- Revision:
- 7:92cbee5144d7
- Parent:
- 6:714ce05307c2
done
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
4180_1 | 0:4a917644acc4 | 1 | #include "mbed.h" |
4180_1 | 0:4a917644acc4 | 2 | #include "EthernetNetIf.h" |
4180_1 | 0:4a917644acc4 | 3 | #include "HTTPClient.h" |
4180_1 | 0:4a917644acc4 | 4 | #include "spdomparser.hpp" |
4180_1 | 0:4a917644acc4 | 5 | #include "spxmlnode.hpp" |
4180_1 | 0:4a917644acc4 | 6 | #include "spxmlhandle.hpp" |
ashea6 | 2:b14f99568253 | 7 | //#include "NokiaLCD.h" |
ashea6 | 2:b14f99568253 | 8 | #include "uLCD_4DGL.h" |
lballiet91 | 1:c96f140b5710 | 9 | #include <string> |
4180_1 | 0:4a917644acc4 | 10 | // Internet of Things weather display example: LCD displays LA current weather via internet Google API |
4180_1 | 0:4a917644acc4 | 11 | // Adapted for LCD from http://mbed.org/users/hlipka/programs/spxmltest_weather/lif782 |
4180_1 | 0:4a917644acc4 | 12 | |
ashea6 | 2:b14f99568253 | 13 | //NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type |
ashea6 | 2:b14f99568253 | 14 | uLCD_4DGL lcd(p28,p27,p29); |
4180_1 | 0:4a917644acc4 | 15 | EthernetNetIf eth; |
4180_1 | 0:4a917644acc4 | 16 | HTTPClient http; |
4180_1 | 0:4a917644acc4 | 17 | HTTPResult result; |
agamemaker | 5:6c3b0bd1f680 | 18 | Serial other(p9, p10); |
4180_1 | 0:4a917644acc4 | 19 | bool completed = false; |
agamemaker | 4:fd8c945b8d79 | 20 | void request_callback(HTTPResult r) |
agamemaker | 4:fd8c945b8d79 | 21 | { |
4180_1 | 0:4a917644acc4 | 22 | result = r; |
4180_1 | 0:4a917644acc4 | 23 | completed = true; |
4180_1 | 0:4a917644acc4 | 24 | } |
4180_1 | 0:4a917644acc4 | 25 | |
agamemaker | 4:fd8c945b8d79 | 26 | void parseWeather(SP_XmlElementNode *node, string loc) |
agamemaker | 4:fd8c945b8d79 | 27 | { |
4180_1 | 0:4a917644acc4 | 28 | //extracts current weather XML data fields for LCD |
4180_1 | 0:4a917644acc4 | 29 | SP_XmlHandle handle(node); |
lballiet91 | 1:c96f140b5710 | 30 | SP_XmlElementNode * condition = handle.getChild( "item" ).getChild("yweather:condition").toElement(); |
lballiet91 | 1:c96f140b5710 | 31 | // Print the name of the city |
agamemaker | 5:6c3b0bd1f680 | 32 | lcd.locate(0,1); |
lballiet91 | 1:c96f140b5710 | 33 | lcd.printf("%s:", loc); |
lballiet91 | 1:c96f140b5710 | 34 | //Print the weather conditions |
agamemaker | 5:6c3b0bd1f680 | 35 | lcd.locate(0,2); |
lballiet91 | 1:c96f140b5710 | 36 | lcd.printf("%s",condition->getAttrValue("text")); |
lballiet91 | 1:c96f140b5710 | 37 | //Print the termperature (in degrees Celcius) |
agamemaker | 5:6c3b0bd1f680 | 38 | lcd.locate(0,3); |
agamemaker | 3:9e55847f25c4 | 39 | lcd.printf("%sF",condition->getAttrValue("temp")); |
4180_1 | 0:4a917644acc4 | 40 | } |
agamemaker | 5:6c3b0bd1f680 | 41 | /* |
agamemaker | 4:fd8c945b8d79 | 42 | void parseTraffic(SP_XmlElementNode *node) |
agamemaker | 4:fd8c945b8d79 | 43 | { |
agamemaker | 4:fd8c945b8d79 | 44 | //extracts current weather XML data fields for LCD |
agamemaker | 4:fd8c945b8d79 | 45 | SP_XmlHandle handle(node); |
agamemaker | 4:fd8c945b8d79 | 46 | SP_XmlElementNode * condition = handle.getChild( "item" ).getChild("yweather:condition").toElement(); |
agamemaker | 4:fd8c945b8d79 | 47 | //Print the weather conditions |
agamemaker | 4:fd8c945b8d79 | 48 | lcd.locate(0,5); |
agamemaker | 4:fd8c945b8d79 | 49 | lcd.printf("%s",condition->getAttrValue("realTime")); |
agamemaker | 4:fd8c945b8d79 | 50 | } |
agamemaker | 5:6c3b0bd1f680 | 51 | */ |
agamemaker | 4:fd8c945b8d79 | 52 | int weather() |
agamemaker | 4:fd8c945b8d79 | 53 | { |
agamemaker | 6:714ce05307c2 | 54 | completed = false; |
4180_1 | 0:4a917644acc4 | 55 | SP_XmlDomParser parser; |
4180_1 | 0:4a917644acc4 | 56 | HTTPStream stream; |
4180_1 | 0:4a917644acc4 | 57 | |
4180_1 | 0:4a917644acc4 | 58 | char BigBuf[512 + 1] = {0}; |
4180_1 | 0:4a917644acc4 | 59 | stream.readNext((byte*)BigBuf, 512); //Point to buffer for the first read |
lballiet91 | 1:c96f140b5710 | 60 | //Yahoo! weather API for selected city - get XML document for parsing |
agamemaker | 5:6c3b0bd1f680 | 61 | HTTPResult r = http.get("https://query.yahooapis.com/v1/public/yql?q=select%20item.condition%20from%20weather.forecast%20where%20woeid%20in%20%28select%20woeid%20from%20geo.places%281%29%20where%20text%3D%22atlanta%2C%20ga%22%29&", &stream, request_callback); |
4180_1 | 0:4a917644acc4 | 62 | while (!completed) { |
4180_1 | 0:4a917644acc4 | 63 | Net::poll(); //Polls the Networking stack |
4180_1 | 0:4a917644acc4 | 64 | if (stream.readable()) { |
4180_1 | 0:4a917644acc4 | 65 | BigBuf[stream.readLen()] = 0; //Transform this buffer in a zero-terminated char* string |
4180_1 | 0:4a917644acc4 | 66 | parser.append( BigBuf, strlen(BigBuf)); // stream current buffer data to the XML parser |
4180_1 | 0:4a917644acc4 | 67 | stream.readNext((byte*)BigBuf, 512); //Buffer has been read, now we can put more data in it |
4180_1 | 0:4a917644acc4 | 68 | } |
4180_1 | 0:4a917644acc4 | 69 | } |
agamemaker | 5:6c3b0bd1f680 | 70 | lcd.locate(0,6); |
4180_1 | 0:4a917644acc4 | 71 | if (result == HTTP_OK) { |
agamemaker | 5:6c3b0bd1f680 | 72 | lcd.printf("Weather complete"); |
4180_1 | 0:4a917644acc4 | 73 | } else { |
agamemaker | 5:6c3b0bd1f680 | 74 | lcd. printf("Weather Error %d", result); |
4180_1 | 0:4a917644acc4 | 75 | return -1; |
4180_1 | 0:4a917644acc4 | 76 | } |
4180_1 | 0:4a917644acc4 | 77 | |
4180_1 | 0:4a917644acc4 | 78 | SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() ); |
agamemaker | 3:9e55847f25c4 | 79 | SP_XmlElementNode * child2 = rootHandle.getChild( "results" ).getChild( "channel" ) |
lballiet91 | 1:c96f140b5710 | 80 | .toElement(); |
agamemaker | 7:92cbee5144d7 | 81 | |
agamemaker | 5:6c3b0bd1f680 | 82 | //lcd.printf(BigBuf); |
agamemaker | 7:92cbee5144d7 | 83 | |
4180_1 | 0:4a917644acc4 | 84 | if ( child2 ) { |
agamemaker | 3:9e55847f25c4 | 85 | parseWeather(child2, "Atlanta"); //parses XML "current-conditions" info |
4180_1 | 0:4a917644acc4 | 86 | } |
agamemaker | 7:92cbee5144d7 | 87 | |
4180_1 | 0:4a917644acc4 | 88 | if ( NULL != parser.getError() ) { |
4180_1 | 0:4a917644acc4 | 89 | lcd.printf( "\n error: %s\n", parser.getError() ); |
4180_1 | 0:4a917644acc4 | 90 | } |
agamemaker | 4:fd8c945b8d79 | 91 | return 0; |
agamemaker | 4:fd8c945b8d79 | 92 | } |
agamemaker | 4:fd8c945b8d79 | 93 | |
agamemaker | 7:92cbee5144d7 | 94 | int traffic(char * traff_domain_name) |
agamemaker | 4:fd8c945b8d79 | 95 | { |
agamemaker | 6:714ce05307c2 | 96 | completed = false; |
agamemaker | 5:6c3b0bd1f680 | 97 | //char traff_domain_name[512] = "http://www.mapquestapi.com/traffic/v1/incidents?key=Vz3y4TYfSQa8b1iUJUv9N6meA9GAAhBH&callback=handleIncidentsResponse&boundingBox=33.977698,-84.662833,33.520957,-84.113516&filters=construction,incidents&inFormat=kvp&outFormat=xml"; |
agamemaker | 7:92cbee5144d7 | 98 | //char traff_domain_name[512] = "https://www.mapquestapi.com/directions/v2/route?key=ZoiBJSzSoqfdNiLD0Z9kZdw4uAN5QUQW&from=710%20Culworth%20Manor%2CAlpharetta%2CGA&to=855%20West%20Peachtree%20St%2CAtlanta%2CCGA&outFormat=xml"; |
agamemaker | 5:6c3b0bd1f680 | 99 | char *tstartXML = "<realTime>"; //RSS XML start title |
agamemaker | 5:6c3b0bd1f680 | 100 | char *tendXML = "</realTime>"; //RSS XML end title |
agamemaker | 5:6c3b0bd1f680 | 101 | char *tsptr; //Start Pointer |
agamemaker | 5:6c3b0bd1f680 | 102 | char *teptr; //End Pointer |
agamemaker | 7:92cbee5144d7 | 103 | char time[4] = ""; |
agamemaker | 5:6c3b0bd1f680 | 104 | int i=0,j=0; |
agamemaker | 7:92cbee5144d7 | 105 | //time = "0000"; |
agamemaker | 4:fd8c945b8d79 | 106 | HTTPStream stream; |
agamemaker | 5:6c3b0bd1f680 | 107 | char BigBuf[2048 + 1] = {0}; |
agamemaker | 5:6c3b0bd1f680 | 108 | stream.readNext((byte*)BigBuf, 2048); //Point to buffer for the first read |
agamemaker | 5:6c3b0bd1f680 | 109 | //Get web page with XML |
agamemaker | 5:6c3b0bd1f680 | 110 | HTTPResult r = http.get(traff_domain_name, &stream, request_callback); |
agamemaker | 4:fd8c945b8d79 | 111 | while (!completed) { |
agamemaker | 5:6c3b0bd1f680 | 112 | Net::poll(); // Polls the Networking stack |
agamemaker | 5:6c3b0bd1f680 | 113 | if (stream.readable()) { // check for end of file |
agamemaker | 5:6c3b0bd1f680 | 114 | BigBuf[stream.readLen()] = 0; // Transform this buffer in a zero-terminated char* string |
agamemaker | 5:6c3b0bd1f680 | 115 | tsptr = BigBuf; |
agamemaker | 5:6c3b0bd1f680 | 116 | // displays titles on LCD from XML "<title>....title text...</title>" |
agamemaker | 5:6c3b0bd1f680 | 117 | do { |
agamemaker | 5:6c3b0bd1f680 | 118 | tsptr = strstr(tsptr,tstartXML); // find <title> in string - NULL if not |
agamemaker | 5:6c3b0bd1f680 | 119 | teptr = strstr(tsptr,tendXML); // find <\title> in string - NULL if not |
agamemaker | 5:6c3b0bd1f680 | 120 | if (tsptr!=NULL) tsptr = tsptr + strlen(tstartXML);// move to char after "<title>" |
agamemaker | 5:6c3b0bd1f680 | 121 | if ((tsptr!=NULL)&&(teptr!=NULL)) { |
agamemaker | 5:6c3b0bd1f680 | 122 | i=0; |
agamemaker | 5:6c3b0bd1f680 | 123 | // loop to display lines on LCD |
agamemaker | 5:6c3b0bd1f680 | 124 | for (j=0; (j)<(strlen(tsptr)-strlen(teptr)); j=j+16) { |
agamemaker | 5:6c3b0bd1f680 | 125 | //lcd.locate(0,(2+(j/16))); |
agamemaker | 5:6c3b0bd1f680 | 126 | // loop to output a line on the LCD |
agamemaker | 5:6c3b0bd1f680 | 127 | for (i=0; ((i<16)&&(tsptr[i+j] != '<')); i++) { |
agamemaker | 5:6c3b0bd1f680 | 128 | //lcd.putc(tsptr[i+j]); |
agamemaker | 5:6c3b0bd1f680 | 129 | time[i+j] = tsptr[i+j]; |
agamemaker | 5:6c3b0bd1f680 | 130 | other.putc(tsptr[i+j]); |
agamemaker | 7:92cbee5144d7 | 131 | wait(.25); |
agamemaker | 5:6c3b0bd1f680 | 132 | } |
agamemaker | 5:6c3b0bd1f680 | 133 | } |
agamemaker | 5:6c3b0bd1f680 | 134 | wait(5); |
agamemaker | 5:6c3b0bd1f680 | 135 | lcd.locate(0,5); |
agamemaker | 5:6c3b0bd1f680 | 136 | } |
agamemaker | 5:6c3b0bd1f680 | 137 | } while (tsptr!=NULL); // No more "<fullDesc>"s in BigBuf to display |
agamemaker | 5:6c3b0bd1f680 | 138 | stream.readNext((byte*)BigBuf, 2048); //Buffer read, now we can put more data in it |
agamemaker | 4:fd8c945b8d79 | 139 | } |
agamemaker | 4:fd8c945b8d79 | 140 | } |
agamemaker | 5:6c3b0bd1f680 | 141 | other.putc('^'); |
agamemaker | 5:6c3b0bd1f680 | 142 | //lcd.printf("%s", BigBuf); |
agamemaker | 5:6c3b0bd1f680 | 143 | lcd.locate(0,7); |
agamemaker | 4:fd8c945b8d79 | 144 | if (result == HTTP_OK) { |
agamemaker | 5:6c3b0bd1f680 | 145 | lcd.printf("Traffic complete"); |
agamemaker | 4:fd8c945b8d79 | 146 | } else { |
agamemaker | 5:6c3b0bd1f680 | 147 | lcd. printf("Traffic Error %d", result); |
agamemaker | 4:fd8c945b8d79 | 148 | return -1; |
agamemaker | 4:fd8c945b8d79 | 149 | } |
agamemaker | 5:6c3b0bd1f680 | 150 | lcd.locate(0,4); |
agamemaker | 5:6c3b0bd1f680 | 151 | lcd.printf("time:%s", time); |
agamemaker | 4:fd8c945b8d79 | 152 | return 0; |
agamemaker | 4:fd8c945b8d79 | 153 | } |
agamemaker | 4:fd8c945b8d79 | 154 | |
agamemaker | 4:fd8c945b8d79 | 155 | int main() |
agamemaker | 4:fd8c945b8d79 | 156 | { |
agamemaker | 7:92cbee5144d7 | 157 | lcd.printf("Reading\n"); |
agamemaker | 7:92cbee5144d7 | 158 | char in[512]; |
agamemaker | 7:92cbee5144d7 | 159 | char url[512]; |
agamemaker | 7:92cbee5144d7 | 160 | int i = 0; |
agamemaker | 7:92cbee5144d7 | 161 | bool flag = false; |
agamemaker | 7:92cbee5144d7 | 162 | while(!flag) { |
agamemaker | 7:92cbee5144d7 | 163 | in[i] = other.getc(); |
agamemaker | 7:92cbee5144d7 | 164 | //other.putc(url[i]); |
agamemaker | 7:92cbee5144d7 | 165 | flag = in[i] == '^'; |
agamemaker | 7:92cbee5144d7 | 166 | i++; |
agamemaker | 7:92cbee5144d7 | 167 | } |
agamemaker | 7:92cbee5144d7 | 168 | in[i-1] = NULL; |
agamemaker | 7:92cbee5144d7 | 169 | sprintf(url, "%s&outFormat=xml", in); |
agamemaker | 7:92cbee5144d7 | 170 | lcd.printf("url:%s\n", url); |
agamemaker | 7:92cbee5144d7 | 171 | wait(5); |
agamemaker | 7:92cbee5144d7 | 172 | lcd.cls(); |
agamemaker | 5:6c3b0bd1f680 | 173 | lcd.locate(0,5); |
agamemaker | 4:fd8c945b8d79 | 174 | lcd.printf("net setup"); |
agamemaker | 5:6c3b0bd1f680 | 175 | lcd.locate(0,5); |
agamemaker | 4:fd8c945b8d79 | 176 | EthernetErr ethErr = eth.setup(60000); |
agamemaker | 4:fd8c945b8d79 | 177 | if (ethErr) { |
agamemaker | 4:fd8c945b8d79 | 178 | lcd.printf("Error in setup"); |
agamemaker | 4:fd8c945b8d79 | 179 | return -1; |
agamemaker | 4:fd8c945b8d79 | 180 | } |
agamemaker | 5:6c3b0bd1f680 | 181 | lcd.printf("net ok "); |
agamemaker | 7:92cbee5144d7 | 182 | traffic(url); |
agamemaker | 5:6c3b0bd1f680 | 183 | weather(); |
agamemaker | 3:9e55847f25c4 | 184 | } |