Contents


Overview

Skill Level: Any Skill Level

This recipe shows you how to create an application using PSA APIs and Bluemix services

Step-by-step

  1. Connect to Bluemix

    Connect to Bluemix : https://console.ng.bluemix.net


     

  2. General architecture

    tuto16

  3. Create your first Internet of Things Starter application

    Go to the catalog and select “Internet of Things Platform Starter”

    tuto22

    Edit the fields and click “Create” button

    tuto32

    In your Bluemix dashbloard, select your new created runtime and check the route url

    tuto42

     

    By clicking on this url, you will access to the Node-Red dashboard. Click on the button to go to the Node-red flow editor

    tuto52

     

    We will create a node flow that returns the n last trip of a specific vehicle :

    The input node is ahttpnode usingREST technology. Then you need to build an URL which contains arguments (see below) to call the PSA API thank’s to anhttp requestnode. Compute the answer of your request from PSA API and finish your workflow with an http responsenode to send to your user the answer of his initial request (by the input node).

     

    tuto62

     

    The URL to call the PSA API is like:            (you can test each flow created by using your favorite browser)

     

    msg.url = “https://api.mpsa.com/api/1.0/trip/last/” +msg.payload.vin+”?limit=”+msg.payload.limit+”&unit=”+msg.payload.unit+”&contract=”+msg.payload.contract+”&client_id=”+msg.payload.clientid;
     

     

    The entry node of this flow is a http requet that require the following parameters:[clientid, vin, contract, unit, limit].

     

    You can import this Node-Red flow with the following code:

    1. Click on the Menu button on the top right corner of the Node-RED flow.
    2. Select Import and then Clipboard.
    3. Copy the content below and paste in the Clipboard and Select OK.

     

    [{“id”:”3039591d.f10966″,”type”:”http request”,”z”:”67668700.dcc518″,”name”:”Get PSA Trip List”,”method”:”GET”,”ret”:”txt”,”url”:””,”x”:186,”y”:317,”wires”:[[“46667c2b.f3f2ec”]]},{“id”:”46667c2b.f3f2ec”,”type”:”json”,”z”:”67668700.dcc518″,”name”:””,”x”:384,”y”:315,”wires”:[[“bf91a1b0.04e708”]]},{“id”:”856d063a.586c18″,”type”:”function”,”z”:”67668700.dcc518″,”name”:”Prepare Trip List URL”,”func”:”msg.url=”https://api.mpsa.com/api/1.0/trip/last/”+msg.payload.vin+”?limit=”+msg.payload.limit+”&unit=”+msg.payload.unit+”&contract=”+msg.payload.contract+”&client_id=”+msg.payload.clientid;nreturn msg;”,”outputs”:1,”noerr”:0,”x”:426,”y”:196,”wires”:[[“3039591d.f10966”]]},{“id”:”3621e0e6.3245e”,”type”:”http in”,”z”:”67668700.dcc518″,”name”:””,”url”:”/psa/trip/list”,”method”:”get”,”swaggerDoc”:””,”x”:137,”y”:198,”wires”:[[“856d063a.586c18”]]},{“id”:”bf91a1b0.04e708″,”type”:”http response”,”z”:”67668700.dcc518″,”name”:””,”x”:556,”y”:316.5,”wires”:[]}]

     

    At the end:

    Do not forget to click on the Deploy button (on the right top corner) to validate you changes.  tuto73

     

     

    Then, we will create a second node flow to get positions for a selected trip

    This node is following the same architecture as before:

     

    tuto81

     

    The new URL to call the PSA API is like:

    msg.url= “https://api.mpsa.com/api/1.0/place/positions/trip/” +msg.payload.vin+”?listsecond=6,12,18,24,30,36,42,48,54,60&near=1&contract=”+msg.payload.contract+”&client_id=”+msg.payload.clientid+”&tripid=”+msg.payload.tripid;

     

    The entry node of this flow is a http request that require the following parameters:[clientid, vin, contract, tripid].

    Moreover, we compute the speed of the car, based on distance between each positions.

    You can import this Node-Red flow with the following code:

    1. Click on the Menu button on the top right corner of the Node-RED flow.
    2. Select Import and then Clipboard
    3. Copy the content below and paste in the Clipboard and Select OK

    [{“id”:”1eb91f2f.24cc41″,”type”:”http request”,”z”:”38f3efa3.ddd6e8″,”name”:”Get PSA Trip Positions”,”method”:”GET”,”ret”:”txt”,”url”:””,”x”:463,”y”:237,”wires”:[[“1634fc56.37d8fc”]]},{“id”:”1634fc56.37d8fc”,”type”:”json”,”z”:”38f3efa3.ddd6e8″,”name”:””,”x”:586,”y”:320,”wires”:[[“5f2d5dd0.169834”]]},{“id”:”6ff286d0.8b66″,”type”:”function”,”z”:”38f3efa3.ddd6e8″,”name”:”Prepare Trip Positions URL”,”func”:”msg.url = “https://api.mpsa.com/api/1.0/place/positions/trip/”+msg.payload.vin+”?listsecond=6,12,18,24,30,36,42,48,54,60&near=1&contract=”+msg.payload.contract+”&client_id=”+msg.payload.clientid+”&tripid=”+msg.payload.tripid;nnode.warn(msg.payload.tripid)n//flow.set(“tripid”, msg.payload);nmsg.tripid = msg.payload;nreturn msg;”,”outputs”:1,”noerr”:0,”x”:294,”y”:169,”wires”:[[“1eb91f2f.24cc41”]]},{“id”:”2f3561ad.700cc6″,”type”:”http in”,”z”:”38f3efa3.ddd6e8″,”name”:””,”url”:”/psa/trip/positions”,”method”:”get”,”swaggerDoc”:””,”x”:137,”y”:60,”wires”:[[“6ff286d0.8b66”]]},{“id”:”d72592da.3cdeb8″,”type”:”http response”,”z”:”38f3efa3.ddd6e8″,”name”:”Http Response”,”x”:936,”y”:470.5,”wires”:[]},{“id”:”5f2d5dd0.169834″,”type”:”function”,”z”:”38f3efa3.ddd6e8″,”name”:”Compute Car Speed”,”func”:”var messages = [];nfor (var i = 0; i < msg.payload.length; i++) {n    var contract = msg.payload[i].contract;n    var vin = msg.payload[i].vin;n    var date = msg.payload[i].lastUpdate;n    date = date.substring(0,4)+”-“+date.substring(4,6)+”-“+date.substring(6,8)+”T”+date.substring(8,10)+”:”+date.substring(10,12)+”:”+date.substring(12,14);n    var d = new Date(date);nn    var keys = Object.keys(msg.payload[i].latitude);n    for (var j = 0; j < keys.length; j++) {n        var key = keys[j];n        var latitude = parseFloat(msg.payload[i].latitude[key]);n        if (latitude !== 0) {n            var second = parseInt(key);n            var d2 = new Date(d.getTime()-60000+(second*1000));n            var longitude = parseFloat(msg.payload[i].longitude[key]);n            var m = {“latitude”:latitude,”longitude”:longitude,”lastUpdate”:date,”mo_id”:vin,”contract”:contract,”trip_id”:msg.tripid,”timestamp”:d2.toISOString(),”ts”:d2.getTime()};n            n            if (messages.length == 0) {n                m.speed = 0;n                m.heading = 0;n            } else {n                lastMessage = messages[messages.length – 1];n                if ( (m.latitude == lastMessage.latitude) && (m.longitude == lastMessage.longitude)) {n                    m.speed = 0;n                    m.heading = lastMessage.heading;n                } else {n                    var dist = Math.acos(Math.sin(lastMessage.latitude * Math.PI / 180)*Math.sin(m.latitude * Math.PI / 180)+Math.cos(lastMessage.latitude * Math.PI / 180)*Math.cos(m.latitude * Math.PI / 180)*Math.cos((lastMessage.longitude-m.longitude) * Math.PI / 180))*6371;n                    var dt = (m.ts – lastMessage.ts)/(1000*3600);n                    if (dt == 0) {n                        m.speed = lastMessage.speed;n                        m.heading = lastMessage.heading;n                    } else {n                        m.speed = Math.abs(dist/dt);n                        var lat1 = lastMessage.latitude * Math.PI / 180;n                        var lng1 = lastMessage.longitude * Math.PI / 180;n                        var lat2 = m.latitude * Math.PI / 180;n                        var lng2 = m.longitude * Math.PI / 180;n                        var X =  Math.cos(lat2) * Math.sin(lng2 – lng1);n                        var Y = (Math.cos(lat1)*Math.sin(lat2))-(Math.sin(lat2)*Math.cos(lat1)*Math.cos(lng2-lng1));n                        var heading = Math.atan2(X,Y);n                        heading = heading * 180 / Math.PI;n                        heading = (heading + 360) % 360;n                        m.heading = heading;n                    }n                }n            }            n            messages.push(m);n        }n    }n}nnmsg.payload = messages;nnode.warn(msg.payload[0]);nreturn msg;nn”,”outputs”:”1″,”noerr”:0,”x”:726,”y”:412,”wires”:[[“d72592da.3cdeb8”]]}]

     

     At the end: 

    Do not forget to click on the Deploy button (on the right top corner) to validate your changes.tuto73

     

     

     Connect your IoT devices to the application with Node-Red

    Watson IoT Platform: Input example: how to send an alert to your connected devices with Node-Red platform.

    tuto101                          tuto91

     

    Double click on the IBM IoT node to open the configuration of the box, and fill empty fields with yours values:

     

     

     

    Watson IoT Platform: Output example: how to send an alert to your connected devices with Node-Red platform

    tuto112

     

    tuto121

     

    Double click on the IBM IoT node to open the configuration of the box, and fill empty fields with yours values:

     

     

     

    Connect another Watson API to your application: Insights for Weather

    Connect another Watson service is very easy with Node-red, which includes a node for almost all services proposed by IBM Watson!

    This example allows the application to connect to the Insights for Weather Watson API to get weather for a given position.

     

    tuto131

     

    Use credentials gave by bluemix to use the selected Watson service with Node-Red.

     

     

    tuto141

      Create another application for the front end use of the user

    Come back to your bluemix webpage, and create a new blank application using the Node.js SDK (or any other language that you will prefer).

     

     

    tuto151

     

    On this program, the job to be done is to call the previous Node-Red application with REST call to obtain information powered by PSA APIs, IoT platform and others Watson APIs like “Insights for Weather”.

    You are free to create an application that will answer to your desire, good luck!

    For more information about how we use the 2 services IoT for Automotive. Continue to read the following document.

     

     

     

     

     

     

  4. Node-Red and 2 services of IoT for Automotive

    There are runtime Node-Red and 2 services of IoT for Automotive used for this application

     Image_doc.1

    The stream “PSA Insights” :

    1.  Call PSA api to recover all the Trip positions
    2.  Calculates the speed and direction of the vehicle for each position (necessary to Driver Behavior)
    3. For each positions, I call the sub-stream “IoT For Automotive”
    4. A message “Done” is displayed when you have processed all positions

    Image_doc21

     

     

     

    The sub-stream “IoT for Automotive” is called for each position of the vehicule :

    1. Make a “mapMatching” on Context Mapping service from the position and of the heading, it takes the best position of the vehicule on the road (GPS precison corrections) and takes the ID of where it is located.
    2. It retrieves the informations of the road with Context Mapping service, which kind of road (RN, Autoroute…)
    3. Accumulate informations and sends it to Driver Behaviour.

       

    Image_doc31

     

     

    Once all information on vehicle movements are injected in Driver Behaviour, you must run a job that calculates the behavior of drivers. This can be done for example nightly. 

    The stream that starts the job is “Driver Behaviour Job”. The stream :

    1. initializes the time interval over which the calculation is required then starts the job

       

    2. call the sub-stream “Job Status” who takes back the job status
    3. call again the sub-stream “Job Status” 5 sec. After if the job is not over.
    4. Indicates when the job is done

    Image_doc41

     

     

    The stream “Trip” retrieves the behavior of a driver during a trip calculated by the Driver Behavior service.First, we get the summary of the trip and then the entire behavior.

    Image_doc51

     

     

     

3 comments on"Create an application using PSA APIs and Watson APIs with Node-Red"

  1. Hello Daniel, where can we get access to PSA API ?

  2. JoachimVandersleyen October 04, 2016

    Hello, when I copy the text of this page to create the nodes in the Import/Clipboard of Node-RED, the IMPORT button does not activate so I cannot import them.
    Was there any changes to the semantic or else ?

Join The Discussion