2018年5月24日 星期四

Using Yahoo's Weather API ----高雄天氣

Most of these rely on API calls to OpenWeatherMap or Weather Underground (Wunderground), and both are great. OpenWeatherMap allows users to build their own weather stations and push data to their servers to be accessed by anyone. Wunderground is owned by The Weather Company and also lets users connect weather stations and contribute to weather/forecast data.
The one downside to pulling data from those two is that you are forced to create an account and use API keys. While I recommend using OpenWeatherMap or Wunderground for most of your needs (they support citizen science contributions!), if you need to obtain weather information without API keys (e.g., classroom), then another alternative exists: Yahoo Weather API.
There are limitations on its use, like noncommercial and 2,000 calls per day, but it still works well for an open API to get weather information. If you click on the link below, you can check out how to craft HTTP calls to the API:
It relies on a query language called “Yahoo Query Language (YQL)” that works similarly to SQL. If I enter the following into the query box, I can get a 10-day forecast for Boulder:
select item.forecast from weather.forecast where woeid in (select woeid from geo.places(1) where text="boulder, co")
The Endpoint also changes (see screenshot), which gives me an HTTP GET request that I can just paste into my code. Note that you might have to click “Test” a few times to get the correct response to show up instead of a "results": null. The YQL test page seems to be slow as of late.
Yahoo Weather API
Yahoo’s Weather API seems to pull its information from weather.com, which is owned by The Weather Channel, so it’s a fairly reliable source.
It would seem that the Yahoo Weather API was originally intended for website-embedded content, but we’re going to use it for a different kind of embedded content: microcontrollers!
For this demo, you’ll just need a SparkFun ESP8266 Thing Dev Board. Follow the hookup guide to install the Arduino library and copy in the following code (changing ssid and password to your WiFi’s SSID and password, respectively):
#include <ESP8266WiFi.h>

// WiFi config
const char ssid[] = "<SSID>";
const char password[] = "<PASSWORD>";

// Server, file, port
const char hostname[] = "query.yahooapis.com";
const String url = "/v1/public/yql?q=select%20item.condition.temp%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22boulder%2C%20co%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&diagnostics=true";
const int port = 80;

// Timeout
unsigned long timeout = 10000;  // ms

// WiFi Client
WiFiClient client;

void setup() {

  // Init Serial
  Serial.begin(9600);
  delay(100);

  // Connect to WiFi
  Serial.print("Connecting to ");
  Serial.print(ssid);
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  // Show we are connected
  Serial.println("Connected!");
}

void loop() {

  unsigned long timestamp;
  int temp;

  // Establish TCP connection
  Serial.print("Connecting to ");
  Serial.println(hostname);
  if ( !client.connect(hostname, port) ) {
    Serial.println("Connection failed");
  }

  // Send GET request
  String req = "GET " + url + " HTTP/1.1\r\n" + 
                "Host: " + hostname + "\r\n" +
                "Connection: close\r\n" +
                "\r\n";
  client.print(req);

  // Wait for response from server
  delay(500);
  timestamp = millis();
  while ( !client.available() && (millis() < timestamp + timeout) ) {
    delay(1);
  }

  // Parse temperature
  if ( client.find("temp\":") ) {
    temp = client.parseInt();
    Serial.print("Local temperature: ");
    Serial.print(temp);
    Serial.println(" F");
  }

  // Flush receive buffer
  while ( client.available() ) {
    client.readStringUntil('\r');
  }

  // Close TCP connection
  client.stop();
  Serial.println();
  Serial.println("Connection closed");

  delay(30000);
}
You can change the URL to whatever you’d like from the Yahoo Weather API page in order to, for example, find the temperature in a different city. Here, I’m fetching the current temperature in Boulder, CO. Open a Serial monitor to get the parsed temperature:
Fetching local weather from Yahoo Weather API

#include <ESP8266WiFi.h>
//高雄市天氣
// WiFi config
const char ssid[] = "PTS-2F";
const char password[] = "";

// Server, file, port
const char hostname[] = "query.yahooapis.com";
const String url = "/v1/public/yql?q=select%20item.condition.temp%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22kaohsiung%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&diagnostics=true";
const int port = 80;

/*
//select item.forecast from weather.forecast where woeid in (select woeid from geo.places(1) where text="boulder, co") 美國波得市
//kaohsiung-city-2306180
// Server, file, port
const char hostname[] = "query.yahooapis.com";
const String url = "/v1/public/yql?q=select%20item.condition.temp%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22boulder%2C%20co%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&diagnostics=true";
const int port = 80; */

// Timeout
unsigned long timeout = 10000;  // ms

// WiFi Client
WiFiClient client;

void setup() {

  // Init Serial
  Serial.begin(115200);
  delay(100);

  // Connect to WiFi
  Serial.print("Connecting to ");
  Serial.print(ssid);
  WiFi.begin(ssid, password);
  while ( WiFi.status() != WL_CONNECTED ) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

  // Show we are connected
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
}

void loop() {

  unsigned long timestamp;
  int temp;

  // Establish TCP connection
  Serial.print("Connecting to ");
  Serial.println(hostname);
  if ( !client.connect(hostname, port) ) {
    Serial.println("Connection failed");
  }

  // Send GET request
  String req = "GET " + url + " HTTP/1.1\r\n" + 
                "Host: " + hostname + "\r\n" +
                "Connection: close\r\n" +
                "\r\n";
  client.print(req);

  // Wait for response from server
  delay(500);
  timestamp = millis();
  while ( !client.available() && (millis() < timestamp + timeout) ) {
    delay(1);
  }

  // Parse temperature
  if ( client.find("temp\":") ) {
    temp = client.parseInt();
    Serial.print(" kaohsiung-city temperature: ");
    Serial.print(temp);
    Serial.print(" F , ");
    float t1= (temp-32) * 5 /9;    //攝氏 = (華氏-32)*5/9
    Serial.print(t1,2);
    Serial.print(" C ");
  }

  // Flush receive buffer
  while ( client.available() ) {
    client.readStringUntil('\r');
  }

  // Close TCP connection
  client.stop();
  Serial.println();
  Serial.println("Connection closed");

  delay(30000);
}






沒有留言:

張貼留言