Using Azure IoT Hub and PowerBI to Visualize Plant Floor Data
In my previous post on the Azure IoT Gateway SDK, 
we put together a Powershell quick start script for Modbus Gateway projects.
In this post we’ll continue the exploration by connecting a Modbus compatible 
Beckhoff BK9100 to Azure IoT Hub, shape our data with Azure Stream Analytics 
and then visualizing the current position of a Dynapar optical encoder with 
Power Bi.
We’ll begin by opening up the Azure Portal, click on the plus icon in the 
upper right corner and search for IoT Hub.  Once the resource is located, 
select Create in the lower left corner.
Configure your IoT Hub with a unique name, select an appropriate scale tier, and make sure to put the hub into it’s own resource group for easy clean-up later.
Navigate to the Shared access policies tab of the IoT Hub and paste the 
Primary key of the service policy into a text file.
Back in the Hub’s primary blade, select the Endpoints tab under messaging. 
In the new blade select the Events entry under Built-in endpoints.  Once 
the new blade opens, copy the Event Hub-compatible name value and the first 
segment of the Event Hub-compatible endpoint value (e.g. 
ihsuprodbyres043dednamespace) into your text file.  We’ll use these values 
in a moment to hook up our Azure Stream Analytics Job.
Next, we’ll need an Azure Stream Analytics(ASA) Job to perform some data 
scaling on the path toward PowerBI.  While this operation could be performed 
in the gateway, ASA provides us an opportunity to sniff/validate our data and 
opens the door to easy persistence, should we so choose.  Again click the plus 
(+) icon in the upper left corner and search for Stream Analytics. Once the 
resource is located, select Create in the blade’s lower left corner.
 
 Configure the 
ASA job with a unique name and place it in the same resource group as the IoT 
Hub.
We now need to patch the IoT Hub as the input for the ASA Job. In the overview 
pane, select the input section under Job Topology, and press add at the top 
of the new blade.  Enter an alias that will be used to reference the input in 
the ASA query.  Make sure that the Source Type is set to Data Stream and 
the Source is marked as Event hub.  Unfortunately, the Event Hub input 
blade will not automatically recognize the IoT Hub’s Event Hub endpoints, so 
we’ll need to set the Subscription field to Provide event hub settings 
manually.  Paste in the Service bus namespace, the ‘Event hub name’ and the 
Event hub policy key from your text file. Finish up by setting the Event up 
policy name to service and press Create.  There is no need to define a 
non-default consumer group and the data will be JSON formatted, encoded as 
UTF-8
Before we define our ASA query we should set up the output hook to PowerBI.
Back under the ASA Job’s overview tab on the main blade, Select the Output 
section under Job Topology and press Add at the top.  Enter power-bi as 
your Output alias, set the Sink to Power BI and press authorize.  You’ll 
be asked to enter your Power BI credentials at the login.  If you don’t 
already have a Power BI account, you can sign up for one 
here.  Once the prompt 
completes login, enter in a Dataset Name and target Table Name.
The last bit of ASA configuration we need to handle is setting up the query.
For now, we’ll build the query based on values that might end up being 
slightly different when you wire up your device.
Navigate the the Query section under Job Topology and select it.  A new 
blade will open up that will list the Input and Output alias previously 
defined and a code editor to enter the ASA query.  We’ll start by selecting 
the observation time stamp and the device type value.  As I noted earlier, we 
need to do some maths to range our encoder value to get the data in shape for 
PowerBI visualization.  To range the encoder value, cast the string to a 
float, devide by the ranges max count (in this case 65535) and multiply by 100 
to push to percentage.
Once the query is entered, select Save at the top and back on the ASA home 
blade, press Start to kick off the job.
We can now turn our attention back to our Modbus device and complete the wiring of it to the gateway. As I noted earlier, I’m using a Beckhoff BK9100, Modbus capable, bus coupler along with a pretty standard Dynapar 2 channel optical incremental encoder (no Z full rev. channel). The Process Image for the coupler includes 8 channels of DIO in front of the mapping space for the encoder module, leaving our counter value located at the second word of the process image. For the astute, the coupler is also confiugred for IPAddres assignment using BootP via Beckhoff’s TCBootP application.
The next step in the process is to register our device with the IoT Hub. While 
there are a number of ways to accomplish this, I suggest you check out our 
iot-samples repository on GitHub.  Begin by either cloning the repo, or just 
download the code directly.  Navigate to Device Management -> csharp and 
open the solution file in Visual Studio (Note, you might also want to checkout 
my Introduction to Azure IoT with Fsharp 
post too!).  With the solution open, set the Create Device Identity project 
as the startup project.  In the config folder, copy the config.default.yaml 
file to config.yaml.  Enter the Host Name for your IoT Hub, and the 
iothubowner’s primary key connection string, which can be found under the 
IoT Hub’s Shared Access policies tab.   Finish up by modifying the 
Nickname and DeviceId values in the config file, they can be any value you 
want.  After you run the project, your device will be registered and a device 
key will be populated in the config file, we’ll need that value shortly.
Open the script from my previous blog post in an Administrative PowerShell ISE session. You’ll need to set at least the following values:
- rootProjectPath
- iotHubName
- deviceName - same as the “deviceId” you registered earlier
- deviceKey - the value from the config file in the Device Management Project
- deviceMac - the mac address of your modbus device
- modbusServerIp - the IP Address of your bus coupler/plc/IO device
- modbusPollingInterval - the number of milliseconds between device polls
- modbusDeviceType - this is the value that is plumbed to ASA
- modbus * - note in the sample script, I’m reading unit 0, with function code 4 (read input registers), reading starting at register 2 (1 based), and only reading 1 word of data … you can see more about Modbus function codes on page 22 of the protocol spec.
Once you fill out your data and run the script, navigate to {projectRootPath} 
-> azure-iot-gateway-sdk -> build -> samples -> modbus -> 
Debug.  Open the modbus_win.json file in a text editor and double check that 
the document looks well formed.
You can now open a PowerShell command prompt in the same folder and issue the following command to begin reading from the device and sending data to Azure > .\ modbus_sample.exe .\modbus_win.json You should see output similar to the following:
 
Assuming you’ve set your polling to something reasonable, like 2000 (2 
seconds), you should be able to run the application for a few hours on a day’s 
allowance for the IoT Hub free scaling tier.
With data flowing to the IoT Hub and onto ASA, log in to Power BI.  Though it 
can take some time to finally show up, the ASA dataset should be visible in 
Datasets group.
Select the Modbus dataset, and expand Visualization and Fields from the toggles on the right of the display.
 
Add a 
Line Chart to the page and set the following values:
- Axis - datetimestamp
- Legend - device-type
- Values - cnt
In the Filters menu for the chart, select the datetimestamp field and set 
the filter type to Top N and show the last 20 items.  This will produce a 
realtime graph of data streaming from the device.  The default polling 
interval should be around 3-4 seconds.  The resulting data will look like 
this!
Happy Coding!