Stat Tracker

Monday, December 29, 2014

Create a Real Life Dashboard with CloudBit and Salesforce.com

This is the second post where I am working with the CloudBit and Salesforce.com. In my first article I made a very simple LED light up when an Opportunity in Salesforce.com moved to a stage of "Closed  Won". The second time around I decided to get a little bit more creative. And what is cooler than recreating your very own Salesforce.com Dashboards in real life with some cardboard, markers, and some littleBits!


littleBits Components

1. USB Power Module
2. CloudBit Module
3. Servo Module

Salesforce.com Components

1. Salesforce.com Report & Dashboards
2. Salesforce.com Analytics API
3. Apex Class to invoke API and littleBits Cloud API


Step 1 - Create a Salesforce.com Summary Report & Dashboard

For this example I created a Salesforce.com Summary Report. The report summarizes the total amount (value) of Opportunities that have a Stage of "Closed Won".


Once you create the report you can create the dashboard with the report as the data source. Create a gauge chart in your dashboard and set the minimum amount to 2 million and the maximum amount to 5 million. The gauge chart maps well to the Servo littleBit. 

Step 2 - Map the littleBit Servo Arc to the Gauge Value Range

The littleBit Servo has two basic modes: Step and Turn. In turn mode you can move the Servo to a specific degree based on the voltage you pass to the Servo. You can set the voltage from 0 to 100. The littleBit Servo has an arc of 145 degrees. So you will lose some precision as you can only set integer voltage values. 

To give a rough voltage value you can take the range of values in your gauge (5 million max - 2 million min - 3 million range) / 145 degrees = 20689 dollars per degree in the chart. The amount of voltage is 1% of voltage = 1.45 degrees (145 degrees / 100% voltage = 1.45 volts percentage per degree).


Step 3 - Call the Salesforce Analytics API to get the Gauge Value

Call the Salesforce.com Analytics API to get the values from the Opportunity Report. You can use the following Apex Class which will call the Salesforce.com API and convert the values into the appropriate voltage for the littleBit API.

public class LittleBitsReportManager 
{
public static LittleBitsManager.LittleBitsOutputPayload runOpptyGaugeReport()
    {
        // Get the report ID
        List <Report> reportList = [SELECT Id,DeveloperName FROM Report where 
            DeveloperName = 'Opportunities_Won'];
        String reportId = (String)reportList.get(0).get('Id');
        
        // Run the report
        Reports.ReportResults results = Reports.ReportManager.runReport(reportId, true);
        System.debug('Synchronous results: ' + results);
        // Run a report synchronously
        
        // Get the first down-grouping in the report, in this case the StageName = 'Closed Won' on Oppty's
        Reports.Dimension dim = results.getGroupingsDown();
        Reports.GroupingValue groupingVal = dim.getGroupings()[0];
        
        // Construct a fact map key, using the grouping key value
        String factMapKey = groupingVal.getKey() + '!T';
        
        // Get the fact map from the report results
        Reports.ReportFactWithDetails factDetails =
            (Reports.ReportFactWithDetails)results.getFactMap().get(factMapKey);
        
        // Get the first summary amount from the fact map
        Reports.SummaryValue sumVal = factDetails.getAggregates()[0];
        System.debug('Summary Label: ' + sumVal.getLabel());
        System.debug('Summary Value: ' + sumVal.getValue());
        
        //Set the output voltage as a percent. More voltage will send the Servo farther down the gauge.
        //Guage Chart = 0% Voltage = 2 Million (Minum Amount on Gauge)
        //Gaute Chart = 100 Voltage = 5 Million (Maximum Amount on Gauge)
        //16666 = 1 voltage percent (3 million between Min and Max / 145 degrees for the servo)
        //2 Million is the bottom of gauge so subtract that from the start.
        integer outputPercent = math.round((((Decimal) sumVal.getValue()) - 2000000) / 20689.655);
        integer duration = -1; //Set the voltage peermamently until it is overwritten
        
        LittleBitsManager.LittleBitsOutputPayload outputPayload = new LittleBitsManager.LittleBitsOutputPayload(outputPercent,duration);
        System.debug(JSON.serialize(outputPayload));
        return outputPayload;
        
        
    }
}


Step 4 - Invoke the littleBits CloudBit API

Using the same Apex Class "LittleBitsManager" I created in the previous post you can call the CloudBit to set the Servo to match the Dashboard Gauge in Salesforce.com.

This simple line of code will reuse our code from the previous article and use the new code above to call the CloudBit.

LittleBitsManager.sendOutputReq(LittleBitsReportManager.runOpptyGaugeReport());

Executing this line of code will make the "Real Life" Dashboard match the Dashboard in Salesforce.com. Let's see it in action!



You can take this to the next step and make this run via Scheduled Apex every 5 minutes to create a dashboard in your office! Put additional reports and charts together with more CloudBits and littleBit components to create multiple chart dashboards!


Saturday, December 27, 2014

Calling littleBits CloudBit from Salesforce.com

littleBits Overview


Recently I received a littleBits CloudBit starter pack as a holiday gift. For those of you who don't know what littleBits are you check them out here: http://littlebits.cc/  I like to think of them as LEGO's for IoT. I have played with Arduino and a few other maker packs but they all have a pretty steep learning curve. For example, to get my Arduino setup to talk to the cloud I had to setup a Node.JS server on my local mac, program an Arduino Sketch, and mess around with a breadboard breaking multiple transistors along the way. I have shaky hands! I like Arduino but I wanted something that was a little easier to play with. Enter littleBits.

Whereas LEGO's have interlocking blocks, littleBits have interlocking components via tiny magnets. There are several types of littleBits that you snap together to form electronic circuits (power, inputs, outputs, and wires). Below is the very simple circuit I built for this demo. It has only 3 blocks. The USB Power, the CloudBit, and a LED Light.




This makes it super simple to create IoT devices. The cloud module I have also automatically syncs to the littleBits cloud and has REST API access, as well as IFTTT connectors. I wanted more granular control over my integration so I chose to call the CloudBit API directly via REST instead of the IFTTT connectors available.

So the first thing I wanted to do was set this up to work with the Salesforce1 Platform.

Pre-Requisites

1. Salesforce1 Developer Login (Free, Sign Up Here)
2. littleBits CloudKit ($100 US, Here)
3. Setup your littleBits Cloud Account via the CloudBit instructions.

Salesforce Setup

Once you have setup the your littleBit cloud account and done the first tutorial that show you how to set it up, you are ready to move on to calling your device from other cloud platforms via the littleBits Cloud HTTP API. From Salesforce.com we will be using APEX HTTP Callouts to send JSON payloads to our littleBit CloudKit device.

Step 1: Setup the Remote Site

In Salesforce.com Setup navigate to "Remote Site Settings" and create a Remote Site Setting with the remote site url of: https://api-http.littlebitscloud.cc
Once the Remote Site Setting is configured we can work on creating our Apex Class.

Step 2: Create the Apex Class "LittleBitsManager".

Using the Developer Console or the Force.com IDE, create the following simple Apex Class. You will replace XXXXX in the URL with your Device ID and xxxxxxxxxxxxxx in the Authorization Header with the Authorization Token in your littleBits cloud setup.


public class LittleBitsManager 
{
    //If we want to make a callout to littleBits from a Trigger, we have to do it Asynchronoushly.
    @future(callout=true) //callout = true allows HTTP Callout from Apex in Async Context
    public static void sendOutputReqAsync(integer percent, integer duration)
    {
        LittleBitsManager.sendOutputReq(new LittleBitsOutputPayload(percent,duration));
    }
    
    //This method will callout to the littleBits Cloud Device
public static void sendOutputReq(LittleBitsOutputPayload outputPayload)
    {
        HttpRequest req = new HttpRequest(); 

          //Set HTTPRequest Method
          req.setMethod('POST');
        
          //Set HTTPRequest header properties, littleBits takes JSON payloads and is RESTful
          req.setHeader('content-type', 'application/json');
          
          //Set the Endpoint (You should make this a Custom Setting but hard coding for example)
          req.setEndpoint('https://api-http.littlebitscloud.cc/v2/devices/xxxxxxxxxxxx/output');
        
          req.setHeader('Authorization','Bearer xxxxxxxxxxxxxxxx');
         
          //Set the HTTPRequest body
          //req.setBody('{"percent":100, "duration_ms":3000}'); 
          req.setBody(JSON.serialize(outputPayload));
          Http http = new Http();
          
           try {
         
                //Execute web service call here
                HTTPResponse res = http.send(req);
        
                //Helpful debug messages
                System.debug(res.toString());
                System.debug('STATUS:'+res.getStatus());
                System.debug('STATUS_CODE:'+res.getStatusCode());
                
        } catch(System.CalloutException e) {
            //Exception handling goes here....
        }
}
    
    //Request Payload in Apex to hold the values we are sending to littleBits.
    public class LittleBitsOutputPayload
    {
        //Percent is the amount of output voltage you want to send from 0 to 100% as an integer
        public integer percent {get;set;}
        //Duration is the time you want to set the voltage. 3000 milliseconds is the default as specified in API docs.
        public integer duration_ms {get;set;}
        
        public LittleBitsOutputPayload(integer inputPercent, integer inputDuration)
        {
            this.percent = inputPercent;
            this.duration_ms = inputDuration;
}
}
    
}


Step 3 - Invoke the LittleBitsManager Apex Class from a Apex Trigger

This simple Apex Trigger will invoke the littleBits Cloud Asynchronously via the above Apex code. Our simple use case is when someone closes an opportunity in Salesforce we should light up an LED.

trigger OpportunityTrigger on Opportunity (after update) 
{
    //Always put this logic in a Trigger Handler never in trigger code
    //For example for littleBits this will be ok
for(Opportunity oppty : trigger.new)
    {
        //If an Opportunity has a been moved to a stage of Closed Won let the team know! Light up the Board via littleBits
        if(oppty.Stage == 'Closed Won' && trigger.oldMap.get(oppty.ID).Stage != 'Closed Won')
        {
            LittleBitsManager.sendOutputReqAsync(100,10000); //100% Power, 10 Seconds (10,000 milliseconds)
        }
    }
}


Step 3 - Test it Out

Here is a simple demonstration showing everything running together. When the Apex Trigger fires the call is made to the CloudBit to light up for 10 seconds. This is a very simple use case but shows how simple it is to get the "plumbing" working between the two platforms. With 100's of different cloudbit connectors and the flexible platform of Salesforce 1 you can literally build any type of IoT application you can think of rapidly!



Note: Reid Carlberg from the Salesforce.com Evangelist team already did a very similar setup here where he uses IFTTT and Twillio / SMS to activate a CloudBit. If you want to see how to use IFTTT and not code directly against the CloudBit API it's worth a view! (https://www.youtube.com/watch?v=Pa9QrwEhuSA)