Last active
December 21, 2017 22:59
-
-
Save Sebchko/da9c7bf2573477429290dce28b5ecb23 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.myrobotlab.service; | |
import java.io.IOException; | |
import java.net.URLEncoder; | |
import org.apache.http.client.ClientProtocolException; | |
import org.json.JSONException; | |
import org.json.JSONObject; | |
import org.json.JSONArray; | |
import org.myrobotlab.framework.ServiceType; | |
import org.myrobotlab.logging.LoggerFactory; | |
import org.slf4j.Logger; | |
/** | |
* A service to query into OpenWeatherMap to get the current weather. For more | |
* info check out http://openweathermap.org This service requires an API key | |
* that is free to register for from Open Weather Map. | |
* | |
*/ | |
public class OpenWeatherMap extends HttpClient { | |
private static final long serialVersionUID = 1L; | |
private String apiBase = "http://api.openweathermap.org/data/2.5/weather?q="; | |
private String apiForecast = "http://api.openweathermap.org/data/2.5/forecast?q="; | |
private String units = "imperial"; // metric | |
private String lang = "en"; | |
private String apiKey = "GET_API_KEY_FROM_OPEN_WEATHER_MAP"; | |
public final static Logger log = LoggerFactory.getLogger(OpenWeatherMap.class); | |
public OpenWeatherMap(String reservedKey) { | |
super(reservedKey); | |
} | |
/** | |
* Return a sentence describing the weather | |
*/ | |
private JSONObject fetch(String location) throws ClientProtocolException, IOException, JSONException { | |
String apiUrl = apiBase + URLEncoder.encode(location, "utf-8") + "&appid=" + apiKey + "&mode=json&units=" + units + "&lang=" + lang; | |
String response = this.get(apiUrl); | |
log.debug("Respnse: {}", response); | |
JSONObject obj = new JSONObject(response); | |
return obj; | |
/** | |
* Return a sentence describing the forecast weather | |
*/ | |
private JSONObject fetch(String location, int nbPeriod) throws ClientProtocolException, IOException, JSONException { | |
String apiUrl = apiForecast + URLEncoder.encode(location, "utf-8") + "&appid=" + apiKey + "&mode=json&units=" + units + "&lang=" + lang + "&cnt=" + nbPeriod; | |
String response = this.get(apiUrl); | |
log.debug("Respnse: {}", response); | |
JSONObject obj = new JSONObject(response); | |
return obj; | |
} | |
/** | |
* retrieve a string list of weather for day (for example:) | |
* | |
*{"coord":{"lon":2.35,"lat":48.86}, | |
*"weather":[{"id":701,"main":"Mist","description":"mist","icon":"50n"}], | |
*"base":"stations", | |
*"main":{"temp":10.37,"pressure":1037,"humidity":93,"temp_min":10,"temp_max":11}, | |
*"visibility":6000, | |
*"wind":{"speed":2.1,"deg":270}, | |
*"clouds":{"all":90}, | |
*"dt":1513884600, | |
*"sys":{"type":1,"id":5610,"message":0.0029,"country":"FR","sunrise":1513842107,"sunset":1513871796}, | |
*"id":2988507,"name":"Paris","cod":200} | |
*/ | |
public String[] fetchWeather(String location) throws ClientProtocolException, IOException, JSONException { | |
String[] result = new String[10]; | |
result[0] = "error"; | |
try { | |
JSONObject obj = fetch(location); | |
result[0] = obj.getJSONArray("weather").getJSONObject(0).get("description").toString(); | |
result[1] = obj.getJSONObject("main").get("temp").toString(); | |
result[2] = location; | |
result[3] = obj.getJSONArray("weather").getJSONObject(0).get("id").toString(); | |
result[4] = obj.getJSONObject("main").get("pressure").toString(); | |
result[5] = obj.getJSONObject("main").get("humidity").toString(); | |
result[6] = obj.getJSONObject("main").get("temp_min").toString(); | |
result[7] = obj.getJSONObject("main").get("temp_max").toString(); | |
result[8] = obj.getJSONObject("wind").get("speed").toString(); | |
result[9] = obj.getJSONObject("wind").get("deg").toString(); | |
return result; | |
} catch (Exception e) { | |
log.error("openweathermap error ( api ? ) : ", e); | |
return result; | |
} | |
} | |
/** | |
* retrieve a string list of weather for the next (max) 5 day (40 period of 3 hours) indicated by PeriodIndex 0 <= | |
* PeriodIndex <= 40 (Note: 0 & 40 give the forecast for all the periods). (for example PeriodIndex=3 :) | |
* | |
* {"city":{"id":2802985,"name":"location","coord":{"lon":5.8581,"lat":50.7019},"country":"FR","population":0}, | |
* "cod":"200", "message":0.1309272, "cnt":3, "list":[ {"dt":1505386800, | |
* "temp":{"day":11.62,"min":10.59,"max":12.39,"night":11.01,"eve":10.59,"morn":10.98}, | |
* "pressure":1006.58, "humidity":100, | |
* "weather":[{"id":502,"main":"Rain","description":"heavy intensity | |
* rain","icon":"10d"}], "speed":6.73, "deg":259, "clouds":92, "rain":17.33}, * | |
* | |
* {"dt":1505473200, | |
* "temp":{"day":14.96,"min":8.43,"max":14.96,"night":8.43,"eve":12.71,"morn":9.46}, | |
* "pressure":1014.87, "humidity":89, | |
* "weather":[{"id":500,"main":"Rain","description":"light | |
* rain","icon":"10d"}], "speed":4.8, "deg":249, "clouds":20, "rain":0.36}, | |
* | |
* {"dt":1505559600, | |
* "temp":{"day":13.85,"min":8.09,"max":14.5,"night":8.44,"eve":12.5,"morn":8.09}, | |
* "pressure":1013.37, "humidity":95, | |
* "weather":[{"id":501,"main":"Rain","description":"moderate | |
* rain","icon":"10d"}], "speed":5.38, "deg":241, "clouds":44, "rain":5.55} ]} | |
* @throws JSONException | |
* @throws IOException | |
* @throws ClientProtocolException | |
*/ | |
public String[] fetchForecast(String location, int periodIndex) throws ClientProtocolException, IOException, JSONException { | |
String[] result = new String[11]; | |
String localUnits = "fahrenheit"; | |
if (units.equals("metric")) { | |
// for metric, celsius | |
localUnits = "celsius"; | |
} | |
if ((periodIndex >= 0)) { | |
JSONObject jsonObj = null; | |
try { | |
jsonObj = fetch(location, (periodIndex)); | |
} catch (IOException | JSONException e) { | |
error("OpenWeatherMap : fetch error",e); | |
return null; | |
} | |
//log.info(jsonObj.toString()); | |
// Getting the list node | |
JSONArray list; | |
try { | |
list = jsonObj.getJSONArray("list"); | |
} catch (JSONException e) { | |
error("OpenWeatherMap : API key or the city is not recognized",e); | |
return null; | |
} | |
// Getting the required element from list by periodIndex | |
JSONObject item = list.getJSONObject(periodIndex); | |
result[0] = item.getJSONArray("weather").getJSONObject(0).get("description").toString(); | |
JSONObject main = item.getJSONObject("main"); | |
result[1] = main.get("temp").toString(); | |
result[2] = location; | |
result[3] = item.getJSONArray("weather").getJSONObject(0).get("id").toString(); | |
result[4] = main.get("pressure").toString(); | |
result[5] = main.get("humidity").toString(); | |
result[6] = main.get("temp_min").toString(); | |
result[7] = main.get("temp_max").toString(); | |
JSONObject wind = item.getJSONObject("wind"); | |
result[8] = wind.get("speed").toString(); | |
result[9] = wind.get("deg").toString(); | |
result[10] = localUnits; | |
} else { | |
error("OpenWeatherMap : Index is out of range"); | |
return null; | |
} | |
return result; | |
} | |
public String getApiBase() { | |
return apiBase; | |
} | |
public String getApiForecast() { | |
return apiForecast; | |
} | |
/** | |
* @param apiBase | |
* The base url that is assocaited with the open weather map api. | |
*/ | |
public void setApiBase(String apiBase) { | |
this.apiBase = apiBase; | |
} | |
public String getUnits() { | |
return units; | |
} | |
/** | |
* @param units | |
* The units, can be either imperial or metric. | |
*/ | |
public void setUnits(String units) { | |
this.units = units; | |
} | |
public String getApiKey() { | |
return apiKey; | |
} | |
/** | |
* @param apiKey | |
* REQUIRED: specify your API key with this method. | |
*/ | |
public void setApiKey(String apiKey) { | |
this.apiKey = apiKey; | |
} | |
public void setLang(String lang) { | |
this.lang = lang; | |
} | |
/** | |
* This static method returns all the details of the class without it having | |
* to be constructed. It has description, categories, dependencies, and peer | |
* definitions. | |
* | |
* @return ServiceType - returns all the data | |
* | |
*/ | |
static public ServiceType getMetaData() { | |
ServiceType meta = new ServiceType(OpenWeatherMap.class.getCanonicalName()); | |
meta.addDescription("This service will query OpenWeatherMap for the current weather. Get an API key at http://openweathermap.org/"); | |
meta.addCategory("data", "weather"); | |
meta.setCloudService(true); | |
return meta; | |
} | |
public static void main(String[] args) { | |
OpenWeatherMap owm = new OpenWeatherMap("weather"); | |
owm.setApiKey("KEY!!"); | |
owm.startService(); | |
try { | |
String[] fetchForecast = owm.fetchForecast("Boston", 0); | |
String sentence = "("+fetchForecast[3]+") In " + fetchForecast[2] + " the weather is " + fetchForecast[0] + ". " + fetchForecast[1] + " degrees " + fetchForecast[10]; | |
log.info(sentence); | |
} catch (ClientProtocolException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} catch (IOException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} catch (JSONException e) { | |
// TODO Auto-generated catch block | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment