Weather forecast

Warning

This project aims at using third party software components. It may not be appropriate if you fancy bottom up coding yourself.

In this project you'll implement a terminal based weather forecast application. Consider the following invocation:

Figure 595. Sample forecast session Slide presentation

Figure 596. Sample forecast invocation Slide presentation
goik@goiki target> java -jar weather-1.0.jar Stuttgart 
1 = Stadtkreis Stuttgart         
2 = Regierungsbezirk Stuttgart 
3 = Stuttgart
4 = Stuttgart Feuerbach
5 = Stuttgart Muehlhausen

Bitte gültige Auswahl 1 bis 5 treffen:2 
Vorhersage für Regierungsbezirk Stuttgart 
Dienstag, 15.05
    23:00:  11°C, Leichter Regen
Mittwoch, 16.05
    02:00:  10°C, Leichter Regen
    05:00:  10°C, Leichter Regen
    08:00:  11°C, Leichter Regen
 ...

Command line argument Stuttgart acting as a search filter.

The filter Stuttgart yields five matching towns / regions.

User choosing second match.

Forecast corresponding to Regierungsbezirk Stuttgart.

The actual weather data is being provided by a web service:

Figure 597. Underlying data provider Slide presentation
https://api.openweathermap.org/data/2.5/forecast?lang=de& 
APPID=7cufdhdcgdhsgdhgfcgsdss67b3&units=metric&id=3214105


{"cod":"200","message":0.0042,"cnt":40,"list":[            
 {"dt":1526428800,"main":{"temp":10.29,"temp_min":10.29,
"temp_max":12.45,"pressure":985.75,"sea_level":1027.48,
"grnd_level":985.75,"humidity":80,"temp_kf":-2.16},
"weather":[{"id":500,"main":"Rain",
"description":"Leichter Regen","icon":"10n"}],"clouds":
{"all":88},"wind":{"speed":1.59,"deg":313.503},"rain":
{"3h":0.315},"sys":{"pod":"n"},"dt_txt":"2018-05-16 00:00:00"},           
{"dt":1526439600,"main": ...

An URL containing an id value corresponding to a uniquely defined town or region. We identify the following components:

lang=de

Provide German localization e.g. «Leichter Regen» in favour of «light rain».

APPID=7cufdhdcgdhsgdhgfcgsdss67b3

This parameter allows for accessing the service: «7cufdhdcgdhsgdhgfcgsdss67b3» is actually a fake value. Your project requires obtaining an APPID token.

units=metric

Favour metric over imperial units.

id=3214105

«3214105» identifies «Regierungsbezirk Stuttgart», see line 262703 in cities.list.json:

"id": 3214105,
"name": "Regierungsbezirk Stuttgart",
"country": "DE",
"coord": {
  "lon": 9.66667,
  "lat": 49.083328
}

https://openweathermap.org/api's reply providing JSON based weather data.


Figure 598. cities.list.json.gz providing cities Slide presentation
[
  {
    "id": 2886241,
    "name": "Regierungsbezirk Köln",
    "country": "DE",
    "coord": {
      "lon": 7.16667,
      "lat": 50.833328
    }
  },
  {
    "id": 3247452,
    "name": "Kreis Euskirchen",
...
]

Figure 599. ma/Copy URL result to file Slide presentation
FileUtils.copyURLToFile(
  "https://api.openweathermap.org/data/2.5/forecast...",
  new File("weatherData.json"));
<dependency>
  <groupId>commons-io</groupId>
  <artifactId>commons-io</artifactId>
  <version>2.6</version>
</dependency>

Figure 600. Parse city data Slide presentation
public class Cities {
  static public final City[] cities;
   ...
}
@Test public void testParsedCityCount() {
  Assert.assertEquals(209579, Cities.cities.length);
}

Figure 601. Parse weather data Slide presentation
public class WeatherDataParser {

  static public final Weather parse(final String jsonWeatherDataFilename)
     throws IOException {
    return ...;
  }
}
@Test public void testParseWeatherData() {
...
  Weather weather = WeatherDataParser.parse(
    "src/main/resources/stuttgart.weather.json");
...

Figure 602. Requirements Slide presentation
  1. The application shall accept a command line parameter like e.g. «Stuttgart» to filter matching cities from cities.list.json.

  2. If a given filter matches multiple locations the user shall have an option for choosing the desired one.

  3. The most recent city id value shall be cached in a file. Subsequent invocations without command line parameter shall provide a current forecast corresponding to this value.

  4. Weather data belonging to a given id value shall be cached locally for 10 minutes. Subsequent weather queries within this period shall be read from cache rather than by accessing https://api.openweathermap.org/... .

    Provide logging to a file rather than to the console to avoid cluttering the user interface. Log cache handling.


Figure 603. Logging Slide presentation
  • Provide logging to a file rather than to the console to avoid cluttering the user interface.

  • Log cache handling.

main INFO  weather.Forecast - Re-using cache file
 '/ma/goik/Forecast/6930414.json' from 196 seconds ago

Tip

See the related skeleton project.