Salesforce IOT for better customer experience and product support

IoT (Internet of Things). Today we live in the world of connected electronic devices. These devices can be individual devices, machines, sensors etc. All these devices generate lot of data. Companies are constantly looking to use this data and improve customer experience and products. In CRM world companies are constantly using data to improve end customer experience and support process. In our regular day to day we come across may connected devices, from mobile phones to cars. In following example we will use car and see how can we use Salesforce IOT to enable car company’s customer reps to provide better service to car owner.

In our use case lets say we have connected car that is able to relay data e.g. Check engine sensor , we are all familiar when it lights up on our dash board. it is sensor relaying diagnostics codes to dashboard. Lets assume this data can be sent and used to provide service to car owner. A car can breakdown anywhere and lets assume at minimum it relays following data. VIN, Latitude, Longitude, Mileage and OBD Code.

{
     "vin": "XXXXXXXXXXXXXXXX",
     "latitude": "37.784173",
     "longitude": "-122.401557",
     "mileage": 51000,
     "obdcode": "P0001"
}

Now we have this information. Lets see how can we use this information to provide better customer experience and support to owner of vehicle using Salesforce.

  • Create case for this VIN.
  • Create task to dispatch recovery vehicle to location of breakdown.
  • Place a call to car owner that we noticed about the breakdown and have dispatched the recovery vehicle.
  • We have mileage so using that we can also suggest if owner wants to schedule car service appointment at the dealer.
  • Use this data to see if similar car models with same mileage have similar issues this information can be used to improve product support.

Lets use this example and implement this in Salesforce IOT using Salesforce IoT Explorer in our developer sandbox.

Create platform event Vehicle Sensor ( Vehicle_Sensor__e ) where data from cars sensor will be delivered. create custom fields on platform event to match the field we discussed earlier ( VIN_Number__c , latitude__c , longitude__c , mileage__c , obd_code__c ).

Vehicle Sensor Platform Event

Create IOT Context “Vehicle Health Status” . A context specifies the sources of data that an orchestration can access. Context matched key field VIN to VIN external id of custom object VIN.

Vehicle Health Status Context

Create IOT orchestration and associate it with a context created earlier. orchestration executes states and rules on data provided by context.

Vehicle Health Check Orchestration States
Vehicle Health Check Orchestration Rules

Activate Your Orchestration and Send Events to Test It , We can use workbench https://workbench.developerforce.com REST Explorer to send POST message to /services/data/v45.0/sobjects/Vehicle_Sensor__e. We can monitor events in Traffic view of orchestration. Orchestration also provide test tool that can be used to post messages to platform event if we do not want to use workbench. In our use case I used workbench we can see cases being created and also location of breakdown being displayed on map. This location information can be used by recovery vehicle.

Customer(Account) and Related cases and related VIN’s for that customer.
Cases created by automated IOT process.
Case created and location plotted using Leaflet map.
Case created and used lightning:map to render google map using location data in events.

Custom lightning component used to display maps using leaflet library , this code can be extended using apex controller to read data from Case object and display real time location information.

<!-- 
    /**
     * @name       : vehicleLocationMap.cmp
     * @category   : Lignining Component
     * @description: Lightning custom for displaying vehicle location using leaflet 
     * @author     : Accletron Consulting   
     * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
     */
 -->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global">
    <ltng:require styles="{!$Resource.leaflet + '/leaflet.css'}" />    
    <ltng:require scripts="{!$Resource.leaflet + '/leaflet.js'}" afterScriptsLoaded="{!c.jsLoaded}" />
    <aura:attribute name="jsLoaded" type="boolean" default="false"/>
    <div aura:id="map"></div>
</aura:component>  
/**
 * @name       : vehicleLocationMapController.js
 * @category   : Lignining Component Controller
 * @description: Client side controller  for displaying leaflet map
 * @author     : Accletron Consulting 
 * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
 */
({
    jsLoaded : function(component, event, helper) {
        component.set("v.jsLoaded", true);
    }
})
/**
 * @name       : vehicleLocationMapRenderer.js
 * @category   : Lignining Component Custom Renderer
 * @description: Client side custom renderer for rendering modify DOM elements created by the framework for a component.
 * @author     : Accletron Consulting 
 * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
 */
({
        rerender: function (component,helper) {
        var nodes = this.superRerender();
        if (!window.L) {
            return nodes;
        } 
        if (!component.map) {
            setTimeout(function() {
                helper.renderMap(component);
            });
        }
    }
})
/**
 * @name       : vehicleLocationMapHelper.js
 * @category   : Lignining Component Helper
 * @description: Client side controller  for displaying leaflet map and marker
 * @author     : Accletron Consulting 
 * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
 */
({

    renderMap : function(component) {
        let initialZoomLevel = 17;
        let latlong = {lat:37.784173, lng:-122.401557};
        
        let coordinates = L.latLng(latlong);

        let mapElement = component.find("map").getElement();

        //Lets user change zoom
        //Sets the view of the map (geographical center and zoom) with the given animation options.
        let map  = window.L.map(mapElement,{zoomControl: true}).setView(coordinates, initialZoomLevel);
        
        //Load and display tile layers on the map
        window.L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        {
            attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        }).addTo(map);
        
        
        //Display clickable/draggable icons on the map
        window.L.marker(coordinates).addTo(map).bindPopup('Breakdown').openPopup();

        component.set("v.map", map);

    }    
})

Custom component used to display map using lightning:map, this code can be extended using apex controller to read data from Case object and display real time location information.

<!-- 
    /**
     * @name       : vehicleLocationMap.cmp
     * @category   : Lignining Component
     * @description: Lightning custom for displaying vehicle location using google maps 
     * @author     : Accletron Consulting   
     * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
     */
 -->
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <!-- attributes -->
    <aura:attribute name="mapMarkers" type="Object"/>
    <aura:attribute name="zoomLevel" type="Integer" />

    <!-- handlers-->
    <aura:handler name="init" value="{! this }" action="{! c.init }"/>

    <!-- the map component -->
    <lightning:map 
        mapMarkers="{! v.mapMarkers }" 
        zoomLevel="{!v.zoomLevel}" />
</aura:component>
/**
 * @name       : vehicleLocationMapControler.js
 * @category   : Lignining Component Controller
 * @description: Client side controller  for displaying google map and marker
 * @author     : Accletron Consulting 
 * @copyright  : Copyright © 2019 Accletron Consulting; All Rights Reserved
 */
({
    init: function (cmp, event, helper) {
        cmp.set('v.mapMarkers', [{
            location:
            {
                'Latitude': '37.790197',
                'Longitude': '-122.396879'
            },title: 'Breakdown Location'
        }]);
        cmp.set('v.zoomLevel', 16);
    }
})

Reference