C# is a modern, common, object-oriented programming language developed and launched by Microsoft in the.NET framework. It combines the powerful features of C++ and the ease of use of Java, enabling developers to build various types of applications, including Windows client applications, Web applications, database applications, mobile applications, and games.
Tencent Cloud IoT Explorer supports integration using C#. This article introduces how to use the MQTTnet Client library in a C# project to achieve connection, topic subscription, uplink and downlink message interaction, and other features with Tencent Cloud IoT Explorer.
Note:
1. This example is based on donet 6.0.
2. The versions of third-party libraries used are as follows:
MQTTnet:v3.0.11
MQTTnet.Extensions.ManagedClient:v3.0.11
Newtonsoft.Json:v12.0.3
NLog:v5.2.3
Overview
A smart light is integrated into the IoT Explorer. Through the IoT Explorer, the brightness, color, and switch of the light can be remotely controlled, and the data reported to the IoT Explorer by the smart light can be accessed in real time.
Preparations
1. Apply for Tencent Cloud IoT Explorer service.
2. One Windows computer with VS2017 and above versions installed.
Operation Steps
Project Creation
1. Log in to IoT Explorer Console, select the platform default public instance or the enterprise instance purchased by user.
2. Click an instance. By default, enter the project list page and click Create a New Project.
Project name: required, input "Smart Light Demo" or other name.
Project description: Fill in the project description according to actual needs.


3. After completing the basic information filling of the project, click Save to complete the creation of the new project.
4. After the project is successfully created, you can create a product.
Create Product
1. Click the project name, enter the product list page, and click Create Product.
2. On the create product page, fill in the basic information of the product.
Product name: required, manually input "Smart Light" or other product names.
Product category: Select the standard category "Intelligent Life" > "Electrical Lighting" > "Lights".
Device type: Select "device".
Authentication method: Select "key authentication".
Communication method: select as needed.
Others are default options.


3. After the product information is filled in, click Save to complete the creation of the product.
4. After the product is successfully created, you can view "Smart Light" on the product list page.
Define the Thing Model of a Product
After selecting the "Light" type, the system automatically generates standard features.


Creating Device
On the device debugging page, click Create New Device. The device name is dev001.


Using C# MQTT Client
Through these steps, you have already successfully obtained the triplet information of the device on Tencent Cloud IoT Explorer. Next, you can use this sample code to integrate with C#.
Input Triplet Information
Click the name of the created device to obtain the device triplet information.
// Cloud-generated triplet informationstatic string PRODUCT_ID = "YOUR_PRODUCT_ID"; // PRODUCT IDstatic string DEVICE_NAME = "YOUR_DEVICE_NAME"; // device namestatic string DEVICE_SECRET = "IOT_PSK"; // device key
Generating MQTT client Connection Parameters
Generate MQTT's
clientId, userName, and password using the triplet information just filled in.// Generate MQTT connection parametersbyte[] decodeBytes = Convert.FromBase64String(DEVICE_SECRET);string clientId = PRODUCT_ID + DEVICE_NAME;string usrNmae = clientId + ";21010406;" + GetNextConnId() +";"+ 0x7fffffff.ToString();string password = ComputeHmacSha1(usrNmae, decodeBytes) + ";hmacsha1";
Create an MQTT client and Connect to the Cloud Platform
IManagedMqttClient mqttClient = new MqttFactory().CreateManagedMqttClient();var mqttOptions = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(10)).WithClientOptions(new MqttClientOptionsBuilder().WithClientId(clientId).WithCredentials(usrNmae, password).WithTcpServer(url, 1883) // Non-tls mode.WithCleanSession().Build()).Build();
If you use TLS encryption for access, configure as follows:
IManagedMqttClient mqttClient = new MqttFactory().CreateManagedMqttClient();var mqttOptions = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(10)).WithClientOptions(new MqttClientOptionsBuilder().WithClientId(clientId).WithCredentials(usrNmae, password).WithTcpServer(url, 8883) // tls integration.WithTls(new MqttClientOptionsBuilderTlsParameters {UseTls = true,IgnoreCertificateChainErrors = true,IgnoreCertificateRevocationErrors = true,AllowUntrustedCertificates = true,}).WithCleanSession().Build()).Build();
Listen for MQTT Connection, Disconnection or Receipt Events
// Listen for connection eventsmqttClient.UseConnectedHandler(e =>{log.Info("mqtt connect success with " + deviceId);return Task.CompletedTask;});// Listen for disconnection eventsmqttClient.UseDisconnectedHandler(e =>{log.Error("mqtt disconnect with " + deviceId);return Task.CompletedTask;});// Listen to received messages.mqttClient.UseApplicationMessageReceivedHandler(e =>{// Process model datastring topic = e.ApplicationMessage.Topic;string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);log.Debug($"down message topic: {topic} paylaod : {payload}");if (topic.Contains("/property/")){// Attribute processing}else if (topic.Contains("/event/")){// Event handling}else if (topic.Contains("/action/")){// Handle behavior}return Task.CompletedTask;});
Connecting to Cloud Platform
// Connect to the platformawait mqttClient.StartAsync(mqttOptions);
Subscribe to the Thing Model topic
// Subscribe to Thing Model topicvar topicFilters = new[]{new MqttTopicFilterBuilder().WithTopic("$thing/down/property/"+deviceId).Build(),new MqttTopicFilterBuilder().WithTopic("$thing/down/event/"+deviceId).Build(),new MqttTopicFilterBuilder().WithTopic("$thing/down/action/"+deviceId).Build()};await mqttClient.SubscribeAsync(topicFilters);
Brightness Example Submission
int brightness = 25;var payload_json = new JObject{["method"] = "report",["clientToken"] = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),["params"] = new JObject{["brightness"] = brightness}};string payload = JsonConvert.SerializeObject(payload_json).ToString();var message = new MqttApplicationMessageBuilder().WithTopic("$thing/up/property/" + deviceId).WithPayload(payload).WithQualityOfServiceLevel(0).WithRetainFlag(false).Build();await mqttClient.PublishAsync(message);
The complete sample code is as follows:
using System;using System.Collections.Generic;using System.Text;using System.Security.Cryptography;using NLog;using MQTTnet;using MQTTnet.Client.Options;using MQTTnet.Extensions.ManagedClient;using Newtonsoft.Json;using Newtonsoft.Json.Linq;namespace IoT.Explorer.Test{class DatatemplateTest{private static Logger log = LogManager.GetCurrentClassLogger();// Cloud-generated triplet informationstatic string PRODUCT_ID = "F2F43QKKA4";static string DEVICE_NAME = "5629fbfa12f4";static string DEVICE_SECRET = "a91V4htL41oILv80lgCeLA==";public static string GetNextConnId(){char[] connId = new char[6];Random random = new Random();for (int i = 0; i < 6 - 1; i++){int flag = random.Next(3);switch (flag){case 0:connId[i] = (char)(random.Next(26) + 'a');break;case 1:connId[i] = (char)(random.Next(26) + 'A');break;case 2:connId[i] = (char)(random.Next(10) + '0');break;}}connId[6 - 1] = '\0';return new string(connId);}public static string ComputeHmacSha1(string inputString, byte[] keyBytes){byte[] inputBytes = Encoding.UTF8.GetBytes(inputString);using (HMACSHA1 hmac = new HMACSHA1(keyBytes)){byte[] hashBytes = hmac.ComputeHash(inputBytes);string hashString = BitConverter.ToString(hashBytes).Replace("-", "").ToLower();return hashString;}}static async Task Main(string[] args){// Generate MQTT connection parametersbyte[] decodeBytes = Convert.FromBase64String(DEVICE_SECRET);string clientId = PRODUCT_ID + DEVICE_NAME;string usrNmae = clientId + ";21010406;" + GetNextConnId() +";"+ 0x7fffffff.ToString();string password = ComputeHmacSha1(usrNmae, decodeBytes) + ";hmacsha1";string url = PRODUCT_ID + ".iotcloud.tencentdevices.com";string deviceId = PRODUCT_ID + "/" + DEVICE_NAME;try{IManagedMqttClient mqttClient = new MqttFactory().CreateManagedMqttClient();var mqttOptions = new ManagedMqttClientOptionsBuilder().WithAutoReconnectDelay(TimeSpan.FromSeconds(10)).WithClientOptions(new MqttClientOptionsBuilder().WithClientId(clientId).WithCredentials(usrNmae, password).WithTcpServer(url, 8883).WithTls(new MqttClientOptionsBuilderTlsParameters {UseTls = true,IgnoreCertificateChainErrors = true,IgnoreCertificateRevocationErrors = true,AllowUntrustedCertificates = true,}).WithCleanSession().Build()).Build();// Listen for connection eventsmqttClient.UseConnectedHandler(e =>{log.Info("mqtt connect success with " + deviceId);return Task.CompletedTask;});// Listen for disconnection eventsmqttClient.UseDisconnectedHandler(e =>{log.Error("mqtt disconnect with " + deviceId);return Task.CompletedTask;});// Listen to received messages.mqttClient.UseApplicationMessageReceivedHandler(e =>{// Process model datastring topic = e.ApplicationMessage.Topic;string payload = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);log.Debug($"down message topic: {topic} paylaod : {payload}");if (topic.Contains("/property/")){// Attribute processing}else if (topic.Contains("/event/")){// Event handling}else if (topic.Contains("/action/")){// Handle behavior}return Task.CompletedTask;});// Connect to the platform.await mqttClient.StartAsync(mqttOptions);Thread.Sleep(2000);// Subscribe to Thing Model topicvar topicFilters = new[]{new MqttTopicFilterBuilder().WithTopic("$thing/down/property/"+deviceId).Build(),new MqttTopicFilterBuilder().WithTopic("$thing/down/event/"+deviceId).Build(),new MqttTopicFilterBuilder().WithTopic("$thing/down/action/"+deviceId).Build()};await mqttClient.SubscribeAsync(topicFilters);int brightness = 0;while (true) {// Submit brightness periodicallyvar payload_json = new JObject{["method"] = "report",["clientToken"] = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),["params"] = new JObject{["brightness"] = brightness}};string payload = JsonConvert.SerializeObject(payload_json).ToString();var message = new MqttApplicationMessageBuilder().WithTopic("$thing/up/property/" + deviceId).WithPayload(payload).WithQualityOfServiceLevel(0).WithRetainFlag(false).Build();await mqttClient.PublishAsync(message);log.Debug("publish message :" + payload);brightness++;if (!mqttClient.IsConnected){break;}Thread.Sleep(10000);}// disconnectawait mqttClient.StopAsync();}catch (Exception ex){var name = ex.GetType().FullName;log.Error("Exception: " + ex.Message);}}}}
Running logs are as follows:
2023-08-09 12:04:20.0860 INFO IoT.Explorer.Test.DatatemplateTest - mqtt connect success with F2F43QKKA4/5629fbfa12f42023-08-09 12:04:21.7918 DEBUG IoT.Explorer.Test.DatatemplateTest - publish message :{"method":"report","clientToken":"1691553861","params":{"brightness":0}}2023-08-09 12:04:21.8791 DEBUG IoT.Explorer.Test.DatatemplateTest - down message topic: $thing/down/property/F2F43QKKA4/5629fbfa12f4 paylaod : {"method":"report_reply","clientToken":"1691553861","code":0,"status":"success"}2023-08-09 12:04:25.6359 DEBUG IoT.Explorer.Test.DatatemplateTest - down message topic: $thing/down/property/F2F43QKKA4/5629fbfa12f4 paylaod : {"method":"control","clientToken":"v2149648760ozOCb::af400362-c384-40dd-b39c-94d82950e1ad","params":{"power_switch":1}}2023-08-09 12:04:29.4171 DEBUG IoT.Explorer.Test.DatatemplateTest - down message topic: $thing/down/property/F2F43QKKA4/5629fbfa12f4 paylaod : {"method":"control","clientToken":"v2146761678bxCmt::295125a1-6b64-4cba-b2ca-036bbef43390","params":{"power_switch":0}}2023-08-09 12:04:31.7989 DEBUG IoT.Explorer.Test.DatatemplateTest - publish message :{"method":"report","clientToken":"1691553871","params":{"brightness":1}}2023-08-09 12:04:31.8919 DEBUG IoT.Explorer.Test.DatatemplateTest - down message topic: $thing/down/property/F2F43QKKA4/5629fbfa12f4 paylaod : {"method":"report_reply","clientToken":"1691553871","code":0,"status":"success"}