Industrial Automation Tech Note 51 - TNIA51
Abstract:
This document explains how to get Crimson 3.1 to talk to Microsoft Azure using the MQTT Connector. It assumes a basic knowledge of Crimson and its operation, and the ability to read and manipulate JSON. For more details on the Crimson Cloud Connectors, please consult the Crimson User Manual.
Products:
CR3000 HMIs / Data Acquisition (DA10 & DA30) / Graphite® HMI / Graphite Controllers
Use Case: Azure Connector
Transferring tag data to Azure.
Required Software:
Crimson 3.1
Required Firmware:
Build 3106.000 or higher
Optional:
For testing purposes, an outline database can be created as described in the Crimson Cloud Connectors: Creating an Outline Database Tech Note. The outline database will be referenced when configuring the connector.
Step 1 – Creating an Account
If you do not have an Azure account, visit http://azure.microsoft.com to create a trial account. The trial account provides sufficient capacity for testing but is unlikely to be suitable for a real deployment. When compared to Crimson’s supported update rates, Azure’s free tier IoT Hub is very limited in terms of messages supported per day. You should, therefore, take care not to leave test devices connected too long if they are configured to update many times per minute.
Step 2 – Creating an IoT Hub
Login to Azure and ensure the left-hand menu strip is expanded. Select the Create a Resource option.
Figure 1.
Referring to Figure 1, in the search box, type a few letters of the phrase IoT Hub until you can select it from the drop-down.
Figure 2.
Referring to Figure 2, click on the Create button to create a new IoT Hub.
Figure 3.
Referring to Figure 3, perform the following actions.
1. In the Subscription drop-down, select the subscription you are using.
2. In the Resource Group section, select Create New and enter a name of Test
3. In the Region drop-down, select an appropriate geographic region.
4. In the IoT Hub Name, enter a suitable name as discussed below.
The IoT Hub name must be globally unique. For this sample, we shall use the name bob-smith-test, but you should obviously use another name that is related to yourself or your organization. If the name has already been used, Azure will not allow you to create the resource.
Next, press the button labeled Next: Size and Scale.
Figure 4.
Referring to Figure 4, set the Pricing and Scale Tier to F1: Free Tier.
Leave the other settings unchanged and press Review + Create, followed by Create.
Azure will churn for a while, and after a delay of what might be several minutes the bell-shaped notification icon in the Azure web console will show a notification that your IoT Hub has been created. Once the creation process has completed, you can refresh your console window to show the resource.
Step 3 – Finding the Host Name
Select the IoT Hub from your Azure dashboard.
Figure 5.
Take note of the hostname highlighted in Figure 5. We shall be using it later when we configure the connector in Crimson. It is typically the IoT Hub Name followed by azure-devices.net.
Step 4 – Creating a Device
We can now create a device within the IoT Hub to correspond to the Crimson device from which we shall be pushing data. To do this, select the IoT Hub in your dashboard and scroll down in the left-hand menu strip until you find the IoT Devices option in the Explorer section. Select this option to show the following.
Figure 6.
Referring to Figure 6, press the New button to create a new device.
Figure 7.
Referring to Figure 7, in the strip that appears on the right-hand side of the window, enter device-01 as the Device ID. Leave the rest of the settings at their defaults (i.e. Symmetric Key, Auto Generate Key and Enable Hub Connection) and press the Save button to create the device.
Your device view will update to show the device.
Figure 8.
Referring to Figure 8, click on device-01 to view its properties.
Figure 9.
Referring to Figure 9, take note of the Primary Key. We shall be using this later when configuring Crimson.
Step 5 – Configuring the Azure Connector
We are now in a position to configure and test the Azure Connector. We shall be configuring it to talk to the device that we created in earlier sections and pushing four of the data tags that we have created. The fifth tag will be used to display the connection status. Start by navigating to the Communications category and select the Azure MQTT settings in the Connectors section.
Figure 10.
Referring to Figure 10, perform the following actions:
1. In the Control section, set the Enable Agent property to Yes.
2. In the MQTT Server section, set the Host Name 1 property to the hostname from Step 3.
3. In the MQTT Server section, set the Client ID property to device-01
4. In the Authentication section, set the Device Key property to the primary key from Step 4.
5. In the Diagnostics section, set the Status property to Status
Next, select the Network tab.
Figure 11.
Referring to Figure 11, set the Server Certificate property to Check Everything. We are able to do this because our database contains an appropriate set of root certificates obtained from Windows. If we do not have root certificates available, we should leave this setting at Ignore.
Next, select the Tag Data 1 tab.
Figure 12.
Referring to Figure 12, perform the following actions:
1. In the Control section, set the Tag Writes property to Enabled.
2. Select the Data Tags category of the Resource Pane.
3. Drag Tag1 through Tag4 into the Contents field in the Editing Pane.
You have now configured Crimson to push Tag1 through Tag4 to the cloud once per second. Press F9 to download the database to your device and check the Status tag on your display or via the web browser. A value of 4 should be displayed, indicating that the cloud connection has been established and that data is being pushed. A value of 0 typically indicates an issue with network connectivity or with DNS, while a value of 1 indicates that the server name was resolved but that the connection could not be established. A value of 3 indicates that the connection has been made, but that data has not been transferred. If you do not see a value of 4, check each item in this note carefully and ensure your Crimson configuration matches your Azure settings.
Step 6 – Interacting with the Device
Now that we have configured Crimson to pass data to the cloud, we can view this data from the Azure web console and optionally write data back to the device. Return to the IoT Hub within the console, and once again select IoT Devices from the Explorers. Select device-01 from the presented list of devices.
Figure 13.
Referring to Figure 13, select the Device Twin option. Please note that Azure will not allow a device twin to grow over 8K (the sum of all the tag names and longest possible tag values, plus all the JSON formatting) in size.
Figure 14.
The device twin is a persistent object that stores the values sent by the device, whether or not those values were included in the latest message. The twin contains data items created by Azure plus the data items reported by your device. If you scroll down a little, you will see the reported object within the properties object.
Figure 15.
The text below shows the part of the twin more clearly with certain items omitted.
"properties": {
"desired": {
[contents ommitted for brevity]
},
"reported": {
"connected": "true",
"device": {
"cellular": {
"valid": "false"
},
"location": {
"valid": "false"
},
"status": "okay"
},
"tags": {
"Tag1": 0,
"Tag2": 0,
"Tag3": 65,
"Tag4": 65
}
},
[balance ommitted for brevity]
As you can see, the twin is a JSON fragment that contains an object called properties, which in turn contains an object called reported. Within this latter object, a further object called tags contains the data tags being pushed by Crimson, and an object called device acts as a placeholder for yet-to-be-supported device status information. Refer to the Crimson User Manual for details on how the format of this JSON fragment can be adjusted to suit your application.
To write data to the device, we must edit the JSON object called desired within the properties object to contain its own tags object that in turn contains the values that we want to write. To modify the twin, click on the twin text within the Azure console and make the following changes.
Figure 16.
It is very important that you get the formatting right when editing the twin. JSON is particularly finicky about commas and other punctuation. The portion that you are creating is shown in red below…
"properties": {
"desired": {
"tags": {
"tag1": 1234
},
"$metadata": {
"$lastUpdated": "2018-09-03T19:12:46.5887281Z"
},
"$version": 1
},
"reported": {
"connected": "true",
[balance ommitted for brevity]
Note the comma at the end of line immediately after the tags object and note the absence of commas at the end of the other lines. JSON requires commas only when another element follows within the current object. If you get this wrong, a red squiggle should appear warning you of your error.
Once you have edited the JSON, press click Save to commit the change. The value of Tag1 in your device should be updated both on the device display and in the reported object in the shadow, although you might have to click Refresh to see this latter change. If this does not happen, check your formatting and check that you have writes enabled in the corresponding tag set.
Writing to Crimson from Azure
In order to write data to a Crimson device from Azure, you need first to configure a tag set that has writes enabled and then contains the tags to which you want to write. If the write is triggered by an update from the device, you may wish to place these tags in a write-only tag set to avoid the write itself triggering another update. This can produce an update storm and result in Azure throttling your connection. Azure will also throttle in other circumstances, so please check your IOT plan if data stops flowing. Recycling the Crimson device appears to reset the quota, but appropriate plans should be selected for production use.
The first thing you need to find is the connection string associated with the service policy of your IOT Hub. This is located under the Shared Access Polices section of the web management console. Select that section, and click on the service entry. In the right-hand pane, click on the Copy icon next to the Connection String with the primary key. This will place the string on your clipboard.
Next go to the Function App that you have created to handle the messages from your device. Select the app itself in the web console and click on Application Settings. Scroll down to Connection String and add a new string of type Custom called IOT containing the connection string you hopefully still have on the clipboard. Save everything and make sure your changes were committed.
You can now go into a function and create some code to send to the device. Below is an example that receives a message from Crimson, parses out some tag values, and then writes one back to the device. The code creates a JSON fragment that mirrors the format of that sent my Crimson…
#r "System.Configuration"
#r "System.Data"
#r "Newtonsoft.Json"
using System;
using System.Configuration;
using System.Data.SqlClient;
using System.Threading.Tasks;
using System.Text;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.Devices;
private static void SendMessage(TraceWriter log, int val)
{
string cs = ConfigurationManager.ConnectionStrings["IOT"].ConnectionString;
ServiceClient client = ServiceClient.CreateFromConnectionString(cs);
string jsonText = "{\"tags\":{\"Tag1\":" + val.ToString() + "}}";
log.Info($"Send is {jsonText}");
var message = new Message(Encoding.ASCII.GetBytes(jsonText));
client.SendAsync("device-01", message);
}
private static bool ParseAndLog(string msg, TraceWriter log, ref int val)
{
log.Info(msg);
JObject json = JObject.Parse(msg);
string conn = json["connected"].ToString();
if( conn == "true" ) {
string tag = json["tags"]["Tag3"].ToString();
log.Info($"Tag value is {tag}");
val = Convert.ToInt32(tag);
return true;
}
log.Info("Not connected");
return false;
}
public static void Run(string myIoTHubMessage, TraceWriter log)
{
int val = 0;
if( ParseAndLog(myIoTHubMessage, log, ref val) ) {
SendMessage(log, val);
}
}
Here is the project.json file for the function…
{
"frameworks": {
"net46":{
"dependencies": {
"Dapper": "1.42.0",
"System.Data.SqlClient":"4.1.0",
"Microsoft.WindowsAzure.ConfigurationManager":"3.2.1",
"Microsoft.Azure.Devices":"1.16.1"
}
}
}
}
NOTE: These samples were developed with Version 1 of the Function Apps API.
Disclaimer
It is the customer's responsibility to review the advice provided herein and its applicability to the system. Red Lion makes no representation about specific knowledge of the customer's system or the specific performance of the system. Red Lion is not responsible for any damage to equipment or connected systems. The use of this document is at your own risk. Red Lion standard product warranty applies.
Red Lion Technical Support
If you have any questions or trouble contact Red Lion Technical Support by clicking here or calling 1-877-432-9908.
For more information: http://www.redlion.net/support/policies-statements/warranty-statement