Improving daily commute

Many cities and public transit systems have started sharing data with the public in the interest of being transparent and improving their operational efficiency. Transit systems have started sharing advisories and transit information to the public through an API. This enables anyone to develop mobile applications that provide information to commuters. At times, it helps with easing congestion within the public transit system.

This example was inspired by a friend who tracks bicycle availability in San Francisco's bike share stations. In the San Francisco Bay Area, there is a bicycle sharing program that enables commuters to rent a bike from a transit center to their work. In a crowded city like San Francisco, bike availability at a given station fluctuates depending on the time of day.

This friend wanted to plan his day based on bike availability at the nearest bike share station. If there are very few bikes left at the station, this friend preferred leaving early to rent a bike. He was looking for a simple hack that would push a notification to his phone when the number of bikes is below a certain threshold. San Francisco's bike share program makes this data available at http://feeds.bayareabikeshare.com/stations/stations.json.

Let's review building a simple example that would enable sending a push notification to a mobile device. In order to send a mobile push notification, we will be making use of If This Then That (IFTTT)—a service that enables connecting your project to third-party services.

In this example, we will parse the data available in JSON format, check the number of available bikes at a specific station, and if it is lower than the specified threshold, it triggers a notification on your mobile device.

Let's get started:

  1. The first step is retrieving the bike availability from the bike share service. This data is available in JSON format at http://feeds.bayareabikeshare.com/stations/stations.json. The data includes bike availability throughout the network.
  2. The bike availability at each station is provided with parameters, such as station ID, station name, address, number of bikes available, and so on.
  3. In this example, we will retrieve the bike availability for the Townsend at 7th station in San Francisco. The station ID is 65 (open the earlier-mentioned link in a browser to find id). Let's write some Python code to retrieve the bike availability data and parse this information:
       import requests 

BIKE_URL = http://feeds.bayareabikeshare.com/stations
/stations.json

# fetch the bike share information
response = requests.get(BIKE_URL)
parsed_data = response.json()

The first step is fetching the data using a GET request (via the requests module). The requests module provides an inbuilt JSON decoder. The JSON data can be parsed by calling the json() function.

  1. Now, we can iterate through the dictionary of stations and find the bike availability at Townsend at 7th, by performing the following steps:
  1. In the retrieved data, each station's data is furnished with an ID. The station ID in question is 65 (open the data feed URL provided earlier in a browser to understand the data format; a snippet of the data is shown in the following screenshot):
A snippet of the bike share data feed fetched using a browser
  1. We need to iterate through the values and determine if the station id matches that of Townsend at 7th:
              station_list = parsed_data['stationBeanList'] 
for station in station_list:
if station['id'] == 65 and
station['availableBikes'] < 2:
print("The available bikes is %d" % station
['availableBikes'])

If there are less than 2 bikes available at the station, we push a mobile notification to our mobile device.

  1. In order to receive mobile notifications, you need to install IF by IFTTT app (available for Apple and Android devices).
  2. We also need to set up a recipe on IFTTT to trigger mobile notifications. Sign up for an account at https://ifttt.com/.

IFTTT is a service that enables creating recipes that connecting devices to different applications and automating tasks. For example, it is possible to log events tracked by the Raspberry Pi Zero to a spreadsheet on your Google Drive.

All recipes on IFTTT follow a common template—if this then that, that is, if a particular event has occurred, then a specific action is triggered. For this example, we need to create an applet that triggers a mobile notification on receiving a web request.

  1. You can start creating an applet using the drop-down menu under your account, as shown in the following screenshot:
Start creating a recipe on IFTTT
  1. It should take you to a recipe setup page (shown as follows). Click on this and set up an incoming web request:
Click on this
  1. Select the Maker Webhooks channel as the incoming trigger:
Select the Maker Webhooks channel
  1. Select Receive a web request. A web request from the Raspberry Pi would act as a trigger to send a mobile notification:
Select Receive a web request
  1. Create a trigger named mobile_notify:
Create a new trigger named mobile_notify
  1. It is time to create an action for the incoming trigger. Click on that.
Click on that
  1. Select Notifications:
Select Notifications
  1. Now, let's format the notification that we would like to receive on our devices:
Setup notification for your device
  1. In the mobile notification, we need to receive the number of bikes available at the bike share station. Click on the + Ingredient button and select Value1.

Format the message to suit your needs. For example, when a notification is triggered by the Raspberry Pi, it would be great to receive a message in the following format: Time to go home! Only 2 bikes are available at Townsend & 7th!

  1. Once you are satisfied with the message format, select Create action and your recipe should be ready!
Create a recipe
  1. In order to trigger a notification on our mobile device, we need a URL to make the POST request and a trigger key. This is available under Services | Maker Webhooks | Settings in your IFTTT account.

The trigger can be located here:

Open the URL listed in the preceding screenshot in a new browser window. It provides the URL for the POST request as well as an explanation on (shown in the following screenshot) how to make a web request:

Making a POST request using the earlier-mentioned URL (key concealed for privacy)
  1. While making a request (as explained in the IFTTT documentation), if we include the number of bikes in the JSON body of request (using Value1), it can be shown on the mobile notification.
  2. Let's revisit the Python example to make a web request when the number of bikes is below a certain threshold. Save the IFTTT URL and your IFTTT access key (retrieved from your IFTTT account) to your code as follows:
       IFTTT_URL = "https://maker.ifttt.com/trigger/mobile_notify/ 
with/key/$KEY"
  1. When the number of bikes is below a certain threshold, we need to make a POST request with the bike information encoded in the JSON body:
       for station in station_list: 
if station['id'] == 65 and
station['availableBikes'] < 3:
print("The available bikes is %d" %
station['availableBikes'])
payload = {"value1": station['availableBikes']}
response = requests.post(IFTTT_URL, json=payload)
if response.status_code == 200:
print("Notification successfully triggered")
  1. In the preceding code snippet, if there are less than three bikes, a POST request is made using the requests module. The number of available bikes is encoded with the key value1:
       payload = {"value1": station['availableBikes']}
  1. Putting it all together, we have this:
       #!/usr/bin/python3 

import requests
import datetime

BIKE_URL = "http://feeds.bayareabikeshare.com/stations/
stations.json"
# find your key from ifttt
IFTTT_URL = "https://maker.ifttt.com/trigger/mobile_notify/
with/key/$KEY"

if __name__ == "__main__":
# fetch the bike share information
response = requests.get(BIKE_URL)
parsed_data = response.json()
station_list = parsed_data['stationBeanList']
for station in station_list:
if station['id'] == 65 and
station['availableBikes'] < 10:
print("The available bikes is %d" % station
['availableBikes'])
payload = {"value1": station['availableBikes']}
response = requests.post(IFTTT_URL, json=payload)
if response.status_code == 200:
print("Notification successfully triggered")

The preceding code sample is available for download along with this chapter as bike_share.py. Try executing it after setting up a recipe on IFTTT. If necessary, adjust the threshold for the number of available bikes. You should receive a mobile notification on your device:

Notification on your mobile device