Last active
March 9, 2024 13:54
-
-
Save Sebchko/8e9e6f1c1cadf2085f6b7e7580062931 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; | |
} | |
/** | |
* retrieve a string list of the current weather (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} | |
*/ | |
/** | |
* Return a sentence describing the forecast weather | |
*/ | |
private JSONObject fetch(String location, int nbDay) throws ClientProtocolException, IOException, JSONException { | |
String apiUrl = apiForecast + URLEncoder.encode(location, "utf-8") + "&appid=" + apiKey + "&mode=json&units=" + units + "&lang=" + lang + "&cnt=" + nbDay; | |
String response = this.get(apiUrl); | |
log.debug("Respnse: {}", response); | |
JSONObject obj = new JSONObject(response); | |
return obj; | |
} | |
/** | |
/** | |
* retrieve a string list of weather for the next (max) 5 day (40 periods of 3 hours) indicated by dayIndex 0 <= | |
* dayIndex <= 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[] fetchCurrentWeather(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(); | |
result[9] = obj.getJSONObject("clouds").get("all").toString(); | |
return result; | |
} catch (Exception e) { | |
log.error("openweathermap error ( api ? ) : ", e); | |
return result; | |
} | |
} | |
public String[] fetchForecast(String location, int dayIndex) throws ClientProtocolException, IOException, JSONException { | |
String[] result = new String[11]; | |
String localUnits = "fahrenheit"; | |
if (units.equals("metric")) { | |
// for metric, celsius | |
localUnits = "celsius"; | |
} | |
if ((dayIndex >= 1) && (dayIndex <= 40)) { | |
JSONObject jsonObj = null; | |
try { | |
jsonObj = fetch(location, (dayIndex)); | |
} 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 dayIndex | |
JSONObject item = list.getJSONObject(dayIndex - 1); | |
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; | |
} | |
@Deprecated | |
public String fetchWeather(String location) throws ClientProtocolException, IOException, JSONException { | |
return fetchForecast(location,0)[0]; | |
} | |
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 void setApiForecast(String apiBase) { | |
this.apiForecast = apiForecast; | |
} | |
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