About smart cities

Smart cities – or intelligent cities – hold the promise for addressing the challenges that city planners will have to face in the coming years: in 2025, around 58% of the world’s population will be living in urban areas and city planners need to be able to provide citizens with the services they expect (transportation and traffic, contained energy consumption, security, etc.) in a sustainable manner. The vision behind smart cities is thus to find means to reach the latter objective and is also about improving the quality of life by leveraging technology – and notably technologies that sit behind the Internet of Things – to offer new interactive urban services.

Implementing the aforementioned interactive services and smart cities applications obviously requires the orchestration and integration of multiple heterogeneous entities, such as: air or traffic sensors, parking monitors, power meters, road signs, mobiles devices, scheduling systems and device management platforms, big data and analytics services, etc. For example, imagine a simple scenario where air quality sensors detect a pollution peek (ozone and/or fine particules): this should automatically trigger the execution of a planning process that would determine and publish max speed thresholds on led traffic road signs; notify people who are subject to allergies through their mobile phones; identify and publish information about alternative routes to avoid traffic congestion; send notifications about the location of available parking spots, to avoid unnecessary circulation.

Apps for smart cities with Predix and Scriptr.io

IoT platforms that are used to implement scenarios such as the one we described above undoubtedly have to provide orchestration and interoperability services, along with scalability and agility. Implementing these scenarios also requires the availability of city-centric APIs (traffic, parkings, public stafety, etc.), such as Predix’s Intelligent Cities API in order to facilitate and accelerate the implementation of interactive services and applications.

Predix is as a cloud-based Platform as a Service developed by General Electric (GE). It is based on Cloud Foundry open source technology. Through Predix, GE exposes its Intelligent Cities APIs that link to data stemming from the monitoring and management of parking; vehicle and pedestrian traffic; and public safety surveillance. The API can be deployed as a micro-service into your Predix account.

If you are involved in the development of smart cities services and/or applications, then you should definitely check our connector to GE’s Intelligent Cities APIs. You might also be interested in checking the sample application described in the next section, to see how to leverage this connector to build applications to enhance city and county planning.

Sample application

As an illustration of how to use the connector, we suggest implementing a simple application that locates available parking spots that exist in a given area, on a map.

parking-app

Get the code

Pre-requisites

Note: Don’t worry if you do not own a Predix account. You still can check the code and the online demo

Importing the connector

In your scriptr.io workspace, you can import the Predix connector by clicking on “+New Script” > “Import Modules”, then selecting “Predix”.

Create an instance of ParkingManager

The ParkingManager class wraps all parking-related APIs. Before obtaining an instance of it, we need to require the “factory” module of the Predix connector.

// Requiring the factory module
var factory = require("modules/predix/factory.js");

Using the factory module, we create an instance of the Predix class, passing either of end users or client (app) credentials (end users and clients must have been defined on Predix). These credentials will be used to obtain an authentication token, sent along with calls made to GE’s APIs. In the below, we assume we already have created a client called “parking2” with “p@rkIng2” as password.

var predix = new factory.Predix({credentials:{clientId:"parking2", clientPassword:"p@rkIng2"}});

Using “predix”, we can now create an instance of ParkingManager:

// get an instance of ParkingManager
var parkingManager = predix.getParkingManager();

Listing parking spots in a given area

Let’s define now a – rectangular – geographical area and get its list of parking spots. To keep the example simple, we only ask for a list of 20 parking spots:

// Specify location of the parking slot
var boundary1 = "32.123:-117"; // upper left corner of the geographical zone
var boundary2 = "32.714983:-117.158012"; // lower right corner of the geographical zone

// To simplify, just list the first 20 parking spots within given boundaries (if any)
var options = {
  "page": 0,
  "size": 20
};
  
var result =  parkingManager.listParkingSpots(boundary1, boundary2, options);  

Determine parkings availability

Each parking spots is monitored by one or many devices (assets) that have a list of in/out events (in = vehicle entering parking spot, out = vehicle leaving parking spot). By comparing the date of the last out event against the last in event of a device, it is easy to know if the corresponding parking spot is available or not (out.timestamp > in.timestamp ==> parking is available).

Let’s first start by obtaining a reference to a device (one device is sufficient):

//Loop through parking spots
var spotList = [];
for (var i = 0; i < result.locations.length; i++) {    
    
  var parkingSpot  =  result.locations[i];

  // Pick the first device that is monitoring a parking spot
  var assetList = parkingSpot.listParkingAssets();
  var asset = assetList[0];  

  // List Vehicles In and Vehicle Out events since the last 48h 
  var endDate = new Date();
  var endTime = endDate.getTime();
  var startTime = endTime - (48 * 3600000);
  var options = {    
    "size":20,
    "page":0
  };
  
  // List Vehicles In events  
  var vIn = asset.listVehiculesIn(startTime, endTime, options);
  // List Vehicles Out events
  var vOut = asset.listVehiculesOut(startTime, endTime, options);
  
  // We assume that the list is in descending order and therefore, the first event on the list is actually the last event that occurred
  var lastEventIn = vIn._embedded.events[0];
  var lastEventOut = vOut._embedded.events[0];

  var parkingSpotData {
    
    spot: parkingSpot["location-uid"],
    location: parkingSpot.coordinates,
    lastIn: new Date(lastEventIn.timestamp), 
    lastOut: new Date(lastEventOut.timestamp),
    available: lastEventOut.timestamp > lastEventIn.timestamp
  };

  spotList.push(parkingSpotData);
}

// Return the list of parking spots + availability
return  spotList;

Save the above code in a script called “parking” that will be invoked to populate the map.

Displaying parking spots on a map

We use Google maps libraries to display the parking spots on a map. The markers’ label will show “A” is the parking spot is available, “F” otherwise. Hovering over a marker displays a tooltip that gives more details about the spot.

<!DOCTYPE html>
<html>
  <head>
    <title>Simple Map</title>
    <meta name="viewport" content="initial-scale=1.0">
    <meta charset="utf-8">
    <style>
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #map {
        height: 100%;
      }
	 .modal {
        display: none; 
        position: fixed;
        z-index: 1; 
        left: 0;
        top: 0;
        width: 100%; 
        height: 100%; 
        overflow: auto;
        background-color: rgb(0,0,0); 
        background-color: rgba(0,0,0,0.4); 
     }
     .modal-content {
        background-color: #FFFFFF;
        margin: 15% auto; 
        padding: 20px;
        border: 1px solid #888;
        font-family:calibri;
        font-size:22px;
        width: 60%;
      }

    </style>
	<script>
      function placeMarkers(spots) {

        for (var i = 0; i < spots.length; i++) {
          
          var locationStr = spots[i].location.P1;
          var location = locationStr.split(",");
          var marker = new google.maps.Marker({
              position: {lat:Number(location[0]), lng: Number(location[1])},
              map: map,
              label: spots[i].available ? "A" : "F",
              title: spots[i].spot + ": " + (spots[i].available ? "Available" : "Full"),
            });
        }
        
        var modal = document.getElementById("loadingMsg");
        modal.style.display = "none";
      }

      function getParkingStatus() {

        var modal = document.getElementById("loadingMsg");
        modal.style.display = "block";
        var xhr = new XMLHttpRequest();
        // Invoking our script. We created a sub-domain called "iotdemos". Replace with you own sub-domain (https://www.scriptr.io/documentation#documentation-sub-domain)
        xhr.open("GET", "https://iotdemos.scriptrapps.io/predix/basicdemo/parking"); 
        xhr.onload = function() {

          var httpResponse = JSON.parse(xhr.responseText);
          placeMarkers(httpResponse.response.result);    
        };

        xhr.onerror = function(error) {

          if (typeof(error) == "object") {
            alert(JSON.stringify(error));
          }else{
            alert(error);
          }
        };
        
        xhr.send();
      }
	</script>
  </head>
  <body onload="getParkingStatus()">
    <div id="map"></div>
    <script>
      
	  var map = null;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: 32.711526, lng: -117.157659}, 
          zoom: 18
        });
      }
    </script>
	<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_GOOGLE_BROWSER_KEY&callback=initMap&libraries=drawing" async defer></script>
	<div id="loadingMsg" class="modal">
       <div class="modal-content">         
         <p>Searching for available parkings. Please wait...</p>
       </div>
    </div>
  </body>
</html>

Try it!

Demo link

Note: the sample application referenced by the above link is using GE simulation data, so kindly bare with us if you experience some latency.

Get the code

The complete code on Github