Pages: [1] 2   Go Down
Author Topic: Weather LCD display via XML  (Read 3323 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good day,

I'm starting a project on displaying the weather of the area i'm in (i.e. Sydney) on a LCD via an arduino uno with ethernet shield.

first, how do you get the xml code? i've seen some examples that links to google weather but the google weather link is not working?
appreciate it if someone could teach me how to get the xml code?

An example or sample code would be helpful too!

cheers!
Logged

CH
Offline Offline
God Member
*****
Karma: 19
Posts: 703
Book Writer "Arduino Praxiseinstieg"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

You can use the Yahoo Weather API. I implemented a project in my book.
See my blog post regarding the stop of Google Weather
http://arduino-praxis.ch/2012/08/google-stoppt-weather-api/

I will post the code soon.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for the info mate. Looking forward to have a look at your code.

cheers!
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 45
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good day Webmeister,

Would you be kind to provide a sample code for the implementation of weather using yahoo's api?

Also if there's anyone that could help, i will appreciate it heaps!

Cheers!
Logged

CH
Offline Offline
God Member
*****
Karma: 19
Posts: 703
Book Writer "Arduino Praxiseinstieg"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

To read the XML from Yahoo Weather API you can use the TextFinder library.

Before you read the weather data you need to get the ID (woeid) from your city.

Example: Zurich/Switzerland
http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20text%3D%22Schweiz%20Z%C3%BCrich%22&format=xml

You will find the ID in the field <woeid>

Code to read the Yahoo Weather API

Code:
//
// Read Yahoo Weather API XML
// 03.09.2012
// http://arduino-praxis.ch


#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xAD };
byte ip[] = { 10, 0, 1, 101 };
byte gateway[] = { 10, 0, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

// Server Yahoo
IPAddress server(87,248,122,181);

EthernetClient client;
TextFinder  finder( client ); 

char place[50];
char hum[30];


void setup()
{
  // Start Ehternet
  Ethernet.begin(mac, ip);
  // Start Serial Port
  Serial.begin(9600);
  Serial.println("Setup...");
}


void loop()
{
  if (client.connect(server, 80))
  {
    // Call Wetter-API
    // w: ID from your City
    // http://weather.yahooapis.com/forecastrss?w=12893459&u=c
    ///
    Serial.println("Connect to Yahoo Weather...");
    client.println("GET /forecastrss?w=12893459&u=c HTTP/1.0");
    client.println("HOST:weather.yahooapis.com\n\n");
    client.println();
    Serial.println("Connected...");
  }
  else
  {
    Serial.println(" connection failed");
  }
 

  if (client.connected())
  {
   
    // Humidity
   if ( (finder.getString("<yweather:atmosphere humidity=\"", "\"",hum,4)!=0) )
   {
     Serial.print("Humidity:  ");
     Serial.println(hum);
   }
   else
   {
     Serial.print("No Humidity Data");
   }
   
   
    // Place/City
    if ( (finder.getString("<title>Conditions for ", " ",place,50)!=0) )
    {
      Serial.print("City:  ");
      Serial.println(place);
    }
   
   
    // Temperature
    if(finder.find("temp=") )
    {
     int temperature = finder.getValue();
     Serial.print("Temp C:  ");
     Serial.println(temperature);
   }
   else
   {
     Serial.print("No Temperature Data");
   }
   
         
  // END XML
  }
  else
  {
    Serial.println("Disconnected");
  }
 
  client.stop();
  client.flush();
  delay(60000);
}


Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for this code, it was super helpful. Does anyone know how to read in the forecasted temperature, not just the current?  I modified the code above to search for "High" or even "Forecast" which seems to appear in the raw RSS feed, but it doesnt return anything.  In fact finder.getvalue() doesn't return anything after the "Current Conditions", to me indicating that somehow the the forecast isn't part of the RSS link in the code above (even thought it appears when you look at the RSS in a browser).  I'm trying to get the forcasted High and Low and the chance of rain as a number (although that doesn't appear in the RSS so I might have to look elsewhere).  Any help would be immensely appreciated.
Logged

CH
Offline Offline
God Member
*****
Karma: 19
Posts: 703
Book Writer "Arduino Praxiseinstieg"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

@dbutt

Please show us your modified code.

To find data in the xml stream you can also use the method finder.getString
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

THanks for the response.  My goal is to use the code to find the high and low temps (and eventually chance of rain) and then change the color of some LEDs depending on the range.  I've left the LED part out until I can figure out how to read in the right information. 
I've tried searching for "High", "Low", "Forecast", which all appear (at least to me) in the source RSS feed.  If I search for "Current Conditions" that does work.

Here is my code:
Code:
//Source:
// Read Yahoo Weather API XML
// 03.09.2012
// http://arduino-praxis.ch


#include <SPI.h>
#include <Ethernet.h>

#include <TextFinder.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x73, 0xC5 };
//byte ip[] = { 10, 0, 1, 101 };
byte gateway[] = { 10, 0, 1, 1 };
byte subnet[] = { 255, 255, 255, 0 };

// Server Yahoo
IPAddress server(87,248,122,181);

EthernetClient client;
TextFinder  finder( client ); 

char place[50];
char hum[30];


void setup()
{
  // Start Ehternet
  Ethernet.begin(mac);
  // Start Serial Port
  Serial.begin(9600);
  Serial.println("Setup...");
}


void loop()
{
  if (client.connect(server, 80))
  {
    // Call Wetter-API
    // w: ID from your City
    // Alternate access
    // http://weather.yahooapis.com/forecastrss?w=12893459&u=c
   
    Serial.println("Connect to Yahoo Weather...");
    //client.println("GET /forecastrss?w=12893459&u=c HTTP/1.0");
    //client.println("HOST:weather.yahooapis.com\n\n");
    client.println("GET /forecastrss/60660_f.xml HTTP/1.0"); //I read on another forum that this link might provide more data
    client.println("HOST:xml.weather.yahoo.com\n\n");
   
    client.println();
    Serial.println("Connected...");
  }
  else
  {
    Serial.println(" connection failed");
  }
 

  if (client.connected())
  {
   
   
    // Humidity
   if ( (finder.getString("<yweather:atmosphere humidity=\"", "\"",hum,4)!=0) )
   {
     Serial.print("Humidity:  ");
     Serial.println(hum);
   }
   else
   {
     Serial.print("No Humidity Data");
   }
   
   
    // Place/City
    if ( (finder.getString("<title>Conditions for ", " ",place,50)!=0) )
    {
      Serial.print("City:  ");
      Serial.println(place);
    }
   
   
    // High Temperature
   // if(finder.find("temp=") )  original
   if(finder.find("Forecast:") )
    {
     long temperature = finder.getValue();
     Serial.print("High Temp F:  ");
     Serial.println(temperature);
   }
   else
   {
     Serial.print("No Temperature Data");
   }
   
   
    // Low Temperature
   // if(finder.find("temp=") ) original
   if(finder.find("Low") )
    {
     long temperature = finder.getValue();
     Serial.print("Low Temp F:  ");
     Serial.println(temperature);
   }
   else
   {
     Serial.print("No Temperature Data");
   }
   
         
  // END XML
  }
  else
  {
    Serial.println("Disconnected");
  }
 
  client.stop();
  client.flush();
  delay(60000);
}
Logged

CH
Offline Offline
God Member
*****
Karma: 19
Posts: 703
Book Writer "Arduino Praxiseinstieg"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I suggest that you copy the XML code to your text editor. Now you can identifiy the data you want to read.

To read the current condition use the following code:
Code:
char currentcond[50];
// Current Condition
    if ( (finder.getString("<b>Current Conditions:</b><br />", "</br> ",currentcond,50)!=0) )
    {
      Serial.print("Current Cond:  ");
      Serial.println(currentcond);
    }
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks.  Yes I can get Current Conditions to print, but not anything after that.  Using your same code for instance and changing Current Conditions for Forecast won't print the Forecast, which is immediately following Current Conditions in the xml code.  I'm also interested just in the number of HIgh and Low, not all the text bit (so that I can easily apply an if statement for a number range).  Any ideas on why your code or the finder.getvalue() wont work for the Forecasted High and Lows.

Thanks.

Dan
Logged

CH
Offline Offline
God Member
*****
Karma: 19
Posts: 703
Book Writer "Arduino Praxiseinstieg"
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As you can see in the XML Code the data for forecast is a datastring divided by HTML-Tags <BR>

Code:
<BR /><b>Forecast:</b><BR />
Tue - Mostly Sunny. High: 77 Low: 55<br />
Wed - Partly Cloudy. High: 68 Low: 48<br />
Thu - Partly Cloudy. High: 66 Low: 50<br />
Fri - Mostly Sunny. High: 68 Low: 48<br />
Sat - Sunny. High: 69 Low: 47<br />
<br />

Therefore it isn't possible to retrieve a value for HIGH by using finder.getValue()
It needs a more complex function to read the single values.

In this case I would use a PHP-Script which reads the data and puts them in a simple xml stream. In the second step you can use your Arduino board to read the output of the xml stream and display them in the serial monitor or on a display.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello all,
This is my first arduino project, and I've modified the script above to output my local temperature as a voltage that I can send to another system.  Any insight as to why I'm not reading any output from pin 3 with this script?:

Quote
//Source:
// Read Yahoo Weather API XML
// 03.09.2012
// http://arduino-praxis.ch

//TempRSS.pde

#include <SPI.h>
#include <Ethernet.h>
#include <TextFinder.h>

byte mac[] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX };
byte ip[] = { XX, XX, XX, XX };
byte gateway[] = { XX, XX, XX, 254 };
byte subnet[] = { 255, 255, 255, 0 };
// Server Yahoo
IPAddress server(87,248,122,181);

EthernetClient client;
TextFinder  finder( client ); 


void setup()
{
  // Start Ehternet
  Ethernet.begin(mac, ip);
  pinMode(3, OUTPUT);
  int pwm = 0;
}


void loop()
{
  if (client.connect(server, 80))
  {
    // http://weather.yahooapis.com/forecastrss?w=2445915&u=f
    client.println("GET /forecastrss?w=2445915&u=f HTTP/1.0");
    client.println("HOST:weather.yahooapis.com\n\n");
    client.println();
  }
  else
  {
    //connection failed- insert fault?
  }
  if (client.connected())
  {
    // Temperature
    if(finder.find("temp=") )
    {
     int temperature = finder.getValue();
     int pwm = (temperature*2.55);
     analogWrite(3, pwm);
   }
   else
   {
     //insert fault output?
   }
  // END XML
  }
  else
  {
    //insert fault output?
  }
  client.stop();
  client.flush();
  delay(60000);
}




Thanks!
-Matt
« Last Edit: February 04, 2013, 07:03:19 pm by m4ttflynn » Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No idea.  But you might try printing the value of pwm before the analogWrite to see what's going on.

-br

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Oh, by the way I'm using an UNO with a PoE ethernet shield... would I need an lcd to troubleshoot?

Thanks!
-Matt
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If it were my problem I'd connect via USB for debugging and use Serial.print().

You can't debug what you can't see.

-br
Logged

Pages: [1] 2   Go Up
Jump to: