Here we go with the second part of the Salesforce IoT playground post.
Read the part 1 post before going on to get the whole context.
Let’s start playing with the Salesforce IoT Explorer Edition by enabling it on the Setup:
The Salesforce IoT platform gives you the means to build business processes with point-and-click: you are still able to create triggers and complex logics, but now you have a simple tool that can be used to orchestrate your IoT information flow (aka Nutellator refills).
As you can see from the image above, new setup items apper:
- Contexts: the configuration that matches platform events (Nutelleven__e) to Salesforce objects (Nutellator__c)
- Orchestrations: this is the logic you build up to create powerful state machines that represent your Nutellators’ live state
- Usage Data: lists all the orchestrations running on your Org
Let’s put all together
The Salesforce IoT Explorer flow is quite simple and works this way:
- IoT data comes from outside in form a HTTP post requests using REST APIs and Platform Events: data can be transformed and modified using Apex Triggers
- Each event is then coupled with actual Saleforce Sobject, the contetual data
- The context is then processed with Orchestrations which define state machines and translates state changes into business actions
- We have now Salesforce actions that can do whatever effect you want (external integrations, Sales / Service actions, …)
The Context
We have already defined the Nutellevent__e platform event and the corresponding Nutellator__c Sobject.
To couple them we should create a new IoT Context from Setup > Salesforce IoT > Contexts > New Context:
After the Context is created, let’s configure what’s inside. Click on Edit > Add Event data:
Select the main event and then the reference device ID that will be source to identify the context objects:
Now click on Add Reference data to complete the configuration:
Select the Nutellator Sobject and the unique field that represents the device:
Complete by hitting Save and then Done.
We are now able to link IoT data to Salesforce objects, such as knowing which device is sending data and which customer (Account) it belongs so.
Our first orchestration
It’s time to add logic to our IoT data to support our refill service.
Click on Setup > Salesforce IoT > Orchestrations > New Orchestration:
Our orchestration is meant to monitor the Nutella levels on the devices, so we are expected to have 3 different states:
- Normal level: level is way above the minimum nutel-level, nothing to do here!
- Warning level: we have reached a warning level, we have enough Nutella but it’s about to drop under the danger threadshold. This state is particularly important if we have different Nutellator for a given customer, and the support technicians could pro-actively refill more than one device when only one is under the danger level
- Empty level: this is the danger level. From now on the Nutellator could finish soon its delicious sauce: it’s time to act not to let the customer without happiness.
To create a new state simply click the + Add State button (don’t worry if your colors differs from the following picture, I had to create and delete more states to match the idea behind the warning and danger ideas):
Switch to the Variables tab and let’s create the warning and empy threadsholds:
These variables should be used to evaluate the level received in the IoT data and to make the proper state transition. Let’s go back to the Rules tab and create a new rule for each state:
From NormalWarning when the level drops under the warning level, from Warning jump to Empty when the level drops under the empty level and finally when in Empty if the level rises up we’ll have a state transition to Warning (which can finally go to Normal.
We are using the Warning level as a “proxy” state of transition between the normal and danger states.
Click on the States tab to have a look at the state machine:
Let’s add some more actions.
When a new event comes, we want to keep track of the level on the Nutellator__c object as you can recall from the Nutellator tab on our Nuterllator 3000 app:
We can add a new action of each state that simply updates for any given incoming Nutellevel__e platform event the corresponding Nutellator__c object:
Click on the Add rule of the rule’s context menĂš (the three dots on the right side of the rule’s title), select Nutellevent__e on the when column, leave condition blank and set Salesforce record on the action column:
Select the Nutellator__c object and click Edit and select the following configuration:
Replicate this action on the other rules: you cannot use the Global Rules, because this kind of rules can only be used to reset context variables (such as counters, i.e. you could decide to activate the support process only if the state machine remains in the empty state for a certain amount of events received and not immediately).
Finally we need to start our support process if the level drops under the empty level.
Before adding this action, create a Nutellator__c lookip field on Nutellator__c object on the CaseEmpty Nutel-level state, stating that a new Case record should be used when state is entered (when column compiled with the State entered and a Salesforce record action):
This is the detail of the so configured Empty level:
Finally activate the Orchestration using the Activate button:
Let’s play the game!
Everything have to start with a platform event, which can be created via:
- Apex code
- HTTP post request
For the purpose of this post, we’ll go with the first method, and here is the execute code (made with the Execute Anonymous plugin of the ORGanizer for Salesforce Chrome & Firefox extension):
Nutellevent__e event1 = new Nutellevent__e(Nutellator_ID__c = 'TI-C04-41R1', Nutellevel__c = 99);
Nutellevent__e event2 = new Nutellevent__e(Nutellator_ID__c = 'T1-C0DE-IRI', Nutellevel__c = 99);
List<Database.SaveResult> results = EventBus.publish(new List<Nutellevent__e>{event1, event2});
We expect 2 different things:
- Level and date/time of event are written on the Nutellator__c objects
- The Orchestration’s state machine should have 2 devices on the Normal state (Orchestration’s Traffic tab)
Now let’s take one of the two devices and make its level drop under 30%:
Nutellevent__e event1 = new Nutellevent__e(Nutellator_ID__c = 'T1-C0DE-IRI', Nutellevel__c = 25);
List<Database.SaveResult> results = EventBus.publish(new List<Nutellevent__e>{event1});
Finally let’s drop under the 10% level and a new Case is expected to be automatically created:
Nutellevent__e event1 = new Nutellevent__e(Nutellator_ID__c = 'T1-C0DE-IRI', Nutellevel__c = 9);
List<Database.SaveResult> results = EventBus.publish(new List<Nutellevent__e>{event1});
And here is the Case related to the device:
With the given configuration you may have experienced a strange behavior: when changing state, the level on the Nutellator__c object is not updated.
This is caused by the order of the rules, that should be evaluated in the correct order: if rule makes a state transition before updatin the record, the record is simply not updated. The solution is to move the update rules before the state transitions:
What’s next
Now that we have all setup on the Salesforce platform, we can setup the real IoT platform (using Heroku?) that will send Salesforce the IoT data (transforming raw data into Platform Events) and I’ll show you how to build an Arduino powered device that will simulate the Nutellator 3000.
See you in the next post!