Contents


Build a weather-tracking application in the cloud, Part 2

Adding IBM Insights for Weather to your PHP app

Comments

This tutorial was written using a previous version of the IBM Bluemix® interface. Given the rapid evolution of technology, some steps and illustrations may have changed.

In Part 1, I showed you how to create a base PHP application and retrieve and store latitude/longitude coordinates for world cities from an online service.

Now let's add the new Insights for Weather service from IBM and start using the city information from Part 1 to track the weather in five world cities of your choice. You'll also see how to host your final application on IBM Bluemix.

Run the example appGet the code for the example app

What you'll need for your app

See Part 1 for the prerequisite knowledge and software.

Step 1. Initialize an Insights for Weather Service instance

Because each location record stored in the database also includes the location's latitude and longitude, you can now integrate your application with the Insights for Weather service. Initially, this service instance will run in an unbound state; this lets you develop the app locally with the service instance itself hosted remotely on Bluemix.

  1. To create a new Insights for Weather instance, log in to your Bluemix account and, from the dashboard, click the Use Services or APIs button. From the resulting list of services, select Insights for Weather. Select the                             Insights for Weather service in the Bluemix catalog
    Select the Insights for Weather service in the Bluemix catalog
  2. Review the description of the service and click CREATE to launch it. Ensure that the App field is set to Leave unbound and that you're using the Free Plan. Launch the                             Insights for Weather service
    Launch the Insights for Weather service
  3. The service instance will now be initialized and you will see a service information page. Note the service name; you'll need it in Step 4. Display the navigation bar on the left and click Service Credentials to view the access details for the service instance. View                             service credentials for access details
    View service credentials for access details
  4. Copy the content of the url field to the weather_uri key in the application's $APP_ROOT/config.php file. This allows your application to connect to the remote Insights for Weather instance and begin retrieving weather data from it.

Step 2. Display current weather data

  1. To use the Insights for Weather service, simply request the service URL shown in the previous section and append the API signature to it. So, for example, a request to the API endpoint https://USERNAME:PASSWORD@twcservice.mybluemix.net/api/weather/v2/observations/current?units=m&language=en-US&geocode=51.50853-0.12574 would produce the following response showing the current weather in London:
     Current weather in                             London response
    Current weather in London response
  2. In particular, the JSON output includes descriptive phrases for the current weather (for example, "Partly cloudy") as well as the current temperature, wind speed, humidity, and other data. To display this same information in your application, update the /index route handler to retrieve the list of stored locations; then connect to the Insights for Weather service as shown above to retrieve the current weather conditions for each location:
    <?php
    // index page handlers
    $app->get('/', function () use ($app) {
      return $app->redirect($app["url_generator"]->generate('index'));
    });
    
    $app->get('/index', function () use ($app, $db) {
      // get list of locations from database
      // for each location, get current weather from Weather service
      $collection = $db->locations;  
      $locations = iterator_to_array($collection->find());
      foreach ($locations as &$location) {
        $uri = $app->config['weather_uri'] . '/api/weather/v2/observations/current?units=m&language=en-US&geocode=' . urlencode(sprintf('%f,%f', $location['lat'], $location['lng']));
        $json = file_get_contents($uri);
        if ($json === FALSE) {
         throw new Exception("Could not connect to Weather API.");  
        }
        $location['weather'] = json_decode($json, true);
      }
      return $app['twig']->render('index.twig', array('locations' => $locations));
    })
    ->bind('index');
  3. Next, update the Twig template at $APP_ROOT/views/index.twig to display this information:
          <div data-role="content">       
            <h2 class="ui-bar ui-bar-a">Current Weather</h2>
            <div class="ui-body">
              <ul data-role="listview" data-split-icon="minus" data-split-theme="d">          
              {% for item in locations %}
                <li>
                  <a href="{{ app.url_generator.generate('forecast', {'id': item._id|trim}) }}" data-ajax="false">{{ item.location }}, {{ item.country }}
                  <br/>
                  {{ item.weather.observation.metric.temp }}&deg; C | {{ item.weather.observation.phrase_22char }}
                  </a>
                  <a href="{{ app.url_generator.generate('delete', {'id': item._id|trim}) }}" data-ajax="false">Remove</a>                 
                </li>
              {% endfor %}
              </ul>
            </div>             
            <div>
              <p><a href="{{ app.url_generator.generate('search') }}" data-ajax="false" data-inline="true" data-role="button" data-icon="plus" data-theme="a">Add Location</a></p>
            </div>             
          </div>
  4. Here's what the template looks like. If you prefer to use icons instead of text, the Insights for Weather service provides a complete set of icons, together with instructions on how to use them.
     Insights for                             Weather service template
    Insights for Weather service template

Notice that each location includes a Delete button next to it, which is linked to the /delete route handler and which passes the location's unique MongoDB record identifier to this handler. The /delete handler deletes the specified record from the MongoDB database:

<?php
// handler to remove location from database
$app->get('/delete/{id}', function ($id) use ($app, $db) {
  $collection = $db->locations;
  $collection->remove(array('_id' => new MongoId($id)));
  return $app->redirect($app["url_generator"]->generate('index'));
})
->bind('delete');

Step 3. Retrieve weather forecasts

  1. Just as you can retrieve the current weather conditions for any location, the Insights for Weather service also lets you retrieve a 10-day weather forecast for that location. Update your API request to https://USERNAME:PASSWORD@twcservice.mybluemix.net/api/weather/v2/forecast/daily/10day?units=m&language=en-US&geocode=51.50853-0.12574, and you'll receive detailed information for both day and night weather conditions, as shown below. Notice the dow and narrative fields in the output, which indicate the day of the week and a forecast snippet for that day, as these are the main fields used by the application.
     10-day                             weather forecast in London response
    10-day weather forecast in London response
  2. To add this feature to your application, create a new handler for the /forecast route, pass it the location identifier in the database, and interpolate the location's coordinates into the API request above. Here's the code:
    <?php
    // handler to display 7-day forecast for selected location
    $app->get('/forecast/{id}', function ($id) use ($app, $db) {
      // look up location record in database
      // connect and get forecast from Weather service
      $collection = $db->locations;
      $location = (array)$collection->findOne(array('_id' => new MongoId($id)));
      $uri = $app->config['weather_uri'] . '/api/weather/v2/forecast/daily/10day?units=m&language=en-US&geocode=' . urlencode(sprintf('%f,%f', $location['lat'], $location['lng']));
      $json = file_get_contents($uri);
      if ($json === FALSE) {
        throw new Exception("Could not connect to Weather API.");  
      }
      $location['weather'] = json_decode($json, true);
      return $app['twig']->render('forecast.twig', array('data' => $location));
    })
    ->bind('forecast');
  3. You can also add a page template for this new handler, and link to it from the main index page. You'll find the template in the code repository for the application. Here's an example of what it looks like:
     Page                             template
    Page template

Step 4. Deploy your app to IBM Bluemix

At this point, the application is complete and ready for you to deploy it to Bluemix.

  1. First, update the application configuration file and modify the database credentials so that they point to your remote MongoDB database deployment.
  2. Then, create the application manifest file, remembering to use a unique host and application name by appending a random string to it (such as your initials).
    ---
    applications:
    - name: weather-tracker-[initials]
    memory: 256M
    instances: 1
    host: weather-tracker-[initials]
    buildpack: https://github.com/cloudfoundry/php-buildpack.git
    stack: cflinuxfs2
  3. The CloudFoundry PHP buildpack doesn't include the PHP MongoDB extension by default, so you must configure the buildpack to enable this extension during deployment. Also, if you'd like to have the Insights for Weather service credentials automatically sourced from Bluemix, update the code to use the Bluemix VCAP_SERVICES variable, as shown below:
    <?php
    if ($services = getenv("VCAP_SERVICES")) {
      $services_json = json_decode($services, true);
      $app->config['weather_uri'] = $services_json["weatherinsights"][0]["credentials"]["url"];
    }
  4. You can now go ahead and push the application to Bluemix, and then bind the Insights for Weather service to it.
    shell> cf api https://api.ng.bluemix.net
    shell> cf login
    shell> cf push
    shell> cf bind-service weather-tracker-[initials] "Insights for Weather-[id]"
    shell> cf restage weather-tracker-[initials]

Now start using the application by browsing to the host specified in the application manifest, for example, http://weather-tracker-[initials].mybluemix.net. If you see a blank page or other errors, try debugging your PHP code to find out where things are going wrong.

Conclusion

The Insights for Weather service makes it easy to add location-specific weather data and forecasts to your mobile or web application. Since the service is accessible over a REST API, you can integrate it with any programming language. And because the service is hosted on Bluemix, connecting it to your Bluemix-hosted application is as simple as binding the service to your application and restaging it.

You can download all the code implemented in this tutorial from the link above, together with the configuration files for the PHP buildpack. I recommend that you get the code, start playing with it, and try adding new features to it. I guarantee you won't break anything, and it will definitely add to your learning. Have fun!


Downloadable resources


Related topics


Comments

Sign in or register to add and subscribe to comments.

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Cloud computing, Mobile development
ArticleID=1026816
ArticleTitle=Build a weather-tracking application in the cloud, Part 2
publish-date=02102016