.NET Core 跨平臺物聯網開發:上報屬性(三)

系列教程目錄

 (一) 鏈接阿里雲IOT

 (二) 設置委託事件

 (三) 上報屬性

 (四)  SDK文檔 屬性、方法、委託、類

 http://pan.whuanle.cn/index.php?dir=uploads/阿里雲IOT/AliIOTXFclient-dll類庫&responsephp

下載三個庫,頭部引入 便可使用html

using AliIOTXFClient;

示例下載地址json

http://pan.whuanle.cn/index.php?dir=uploads/阿里雲IOT/demo示例c#

 本章示例 AliIOTXF.Three服務器

定義產品模型-屬性

打開阿里雲IOT控制檯 https://iot.console.aliyun.com/productdom

點擊產品,打開 --功能定義,而後新建自定義功能ide

 

定義兩個屬性

注意都用小寫,注意都用小寫!透傳數據和Json上傳,都是區分大小寫的。應當統一小寫,避免命名衝突。尤爲使用模型存儲數據,有些字段會與關鍵字衝突,能夠把字段部分大寫,上傳時轉化爲 json,字符所有轉小寫便可。post

讀寫權限,只讀,表示只能從客戶端發送屬性數據到服務器,可讀可寫表示服務器能夠向客戶端設置此屬性的值。阿里雲

 查看屬性

添加好的屬性,打開設備-運行狀態能夠看到spa

 

編寫客戶端設備模型

阿里雲官方文檔 屬性、事件、服務 https://help.aliyun.com/document_detail/89301.html?spm=5176.11065259.1996646101.searchclickresult.5d587dafQbHe20

這裏主要說Json上傳,透傳比較麻煩,可是 XF SDK 是支持的,後面補充透傳方法。

設備屬性上傳JSON格式

{
  "id": "123",
  "version": "1.0",
  "params": {
    "屬性1": {
      "value": "on",
      "time": 1524448722000
    },
    "屬性2": {
      "value": 23.6,
      "time": 1524448722000
    }
  },
  "method": "thing.event.property.post"
}

params 裏面,放置屬性,屬性有兩個參數,value:值,time:時間

在下面裏添加一個新文件 TestModel.cs

文件內容:

 public class TestModel
    {
        public string id { get; set; }
        public string version { get; set; }

        public Params paramS { get; set; }
        public TestModel()
        {
            paramS = new Params();
        }

        public class Params
        {
            public Cpuwd cpuwd { get; set; }
            public Cpuxh cpuxh { get; set; }
            public Params()
            {
                cpuwd = new Cpuwd();
                cpuxh = new Cpuxh();
            }
            public class Cpuwd
            {
                public float value { get; set; }
                public long time { get; set; }
            }
            public class Cpuxh
            {
                public float value { get; set; }
                public long time { get; set; }
            }
        }
        public string methoD { get; set; }
    }

上面就是定義的模型,後面轉爲Json便可上傳數據。模型根據實際狀況自定義。

上一章使用的最後完整代碼,咱們繼續使用此項目代碼:

    class Program
    {
        static void Main(string[] args)
        {
            // 建立鏈接對象
            XFMQTT client = new XFMQTT("a1BiPoNawLI", "Raspberry");
            // 初始化客戶端配置
            client.Init("2NOaBeqXcIzLQEhlJFEfKbWeug0o3m0c", "cn-shanghai");
            // 要訂閱的Topic
            string[] topic = { client.CombineHeadTopic("PubData") };

            // 使用自定義的委託事件
            事件類 事件 = new 事件類();
            client.PubEventHandler += 事件.收到消息;
            client.PubedEventHandler += 事件.重複收到消息;
            client.SubedEventHandler += 事件.發佈消息時;
            client.UnSubedEventHandler += 事件.發送失敗;
            client.ConnectionClosedEventHandler += 事件.斷開鏈接;
            //client.add
            // 鏈接服務器
            client.ConnectMqtt(topic);

            while (true)
            {
                string str = Console.ReadLine();

                // 推送內容到特定的 Topic
                client.Subscribe(client.CombineHeadTopic("SubData"), str);
            }

            Console.ReadKey();
        }
    }
    public class 事件類
    {
        public  void 收到消息(object sender, MqttMsgPublishEventArgs e)
        {
            Console.WriteLine("topic名稱:" + e.Topic);
            Console.WriteLine("接收時間:" + DateTime.Now.ToLongDateString());
            Console.WriteLine("消息內容:\n" + Encoding.ASCII.GetString(e.Message));
        }
        public  void 重複收到消息(object sender, MqttMsgPublishedEventArgs e)
        {
            Console.WriteLine("接收時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId + "    Is Published: " + e.IsPublished);
        }
        public void 發佈消息時(object sender, MqttMsgSubscribedEventArgs e)
        {
            Console.WriteLine("向服務器發送了消息");
            Console.WriteLine("發送時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId);
            Console.WriteLine("QOS 爲 :    " + Encoding.UTF8.GetString(e.GrantedQoSLevels));
        }
        public void 發送失敗(object sender, MqttMsgUnsubscribedEventArgs e)
        {
            Console.WriteLine("消息發送失敗 ");
            Console.WriteLine("時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("失敗的消息 MessageId:    " + e.MessageId);
        }
        public  void 斷開鏈接(object sender, EventArgs e)
        {
            Console.WriteLine("日。。。鏈接斷開了: " + DateTime.Now.ToLongTimeString());
        }
    }
View Code

刪除這一行

            // 使用默認事件方法
            client.UseDefaultEventHandler();

 

上報屬性

刪除 while(true) 語句內的代碼

改爲

   Thread.Sleep(1000);

                //模擬數據
                // cpu溫度
                float cpuwd = (float)(new Random()).Next(0, 120) + (float)(new Random()).NextDouble();
                // cpu消耗
                float cpuxh = (float)(new Random()).Next(0, 99) + (float)(new Random()).NextDouble();

                // 模型對象
                TestModel model = new TestModel
                {
                    id = "123456",      //自定義
                    version = "1.0",    //固定!
                    methoD = "thing.event.property.post",    //固定!
                };

                // 數據和時間戳
                model.paramS.cpuwd.value = cpuwd;
                model.paramS.cpuwd.time = 1524448722000;
                model.paramS.cpuxh.value = cpuxh;
                model.paramS.cpuxh.time = 1524448722000;

                // 推送內容到特定的 Topic
                client.Thing_Property_Post<TestModel>(model, true);

 

而後運行程序,查看阿里雲IOT--設備--運行狀態--數據變化

 

若是你有留意,會發現時間不是實時的。

增長一個方法獲取時間戳的方法(偷別人的)

        /// <summary>  
        /// 將c# DateTime時間格式轉換爲Unix時間戳格式  
        /// </summary>  
        /// <param name="time">時間</param>  
        /// <returns>long</returns>  
        public static long ConvertDateTimeToInt()
        {
            System.DateTime time = DateTime.Now;
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000調整爲13位      
            return t;
        }

把 while(true)的代碼修改

 while (true)
            {
                Thread.Sleep(1000);

                //模擬數據
                // cpu溫度
                float cpuwd = (float)(new Random()).Next(0, 120) + (float)(new Random()).NextDouble();
                // cpu消耗
                float cpuxh = (float)(new Random()).Next(0, 99) + (float)(new Random()).NextDouble();

                // 模型對象
                TestModel model = new TestModel
                {
                    id = "123456",      //自定義
                    version = "1.0",    //固定!
                    methoD = "thing.event.property.post",    //固定!
                };

                // 數據和時間戳
                model.paramS.cpuwd.value = cpuwd;
                model.paramS.cpuwd.time = ConvertDateTimeToInt();
                model.paramS.cpuxh.value = cpuxh;
                model.paramS.cpuxh.time = ConvertDateTimeToInt();

                // 推送內容到特定的 Topic
                client.Thing_Property_Post<TestModel>(model, true);
            }

再次查看數據

 

因爲使用隨機數的範圍比較大,波動太大了,不太符合常規,因此數據報表很差看。這個要根據實際狀況本身調整一下範圍。

筆者把cpu消耗調到 40-50

 

完整代碼以下

    class Program
    {
        static void Main(string[] args)
        {
            // 建立鏈接對象
            XFMQTT client = new XFMQTT("a1BiPoNawLI", "Raspberry");
            // 初始化客戶端配置
            client.Init("2NOaBeqXcIzLQEhlJFEfKbWeug0o3m0c", "cn-shanghai");
            // 要訂閱的Topic
            string[] topic = { client.CombineHeadTopic("PubData")};

            // 使用自定義的委託事件
            事件類 事件 = new 事件類();
            client.PubEventHandler += 事件.收到消息;
            client.PubedEventHandler += 事件.重複收到消息;
            client.SubedEventHandler += 事件.發佈消息時;
            client.UnSubedEventHandler += 事件.發送失敗;
            client.ConnectionClosedEventHandler += 事件.斷開鏈接;
            //client.add
            // 鏈接服務器
            client.ConnectMqtt(topic);

            while (true)
            {
                Thread.Sleep(1000);

                //模擬數據
                // cpu溫度
                float cpuwd = (float)(new Random()).Next(40, 60) + (float)(new Random()).NextDouble();
                // cpu消耗
                float cpuxh = (float)(new Random()).Next(30, 40) + (float)(new Random()).NextDouble();

                // 模型對象
                TestModel model = new TestModel
                {
                    id = "123456",      //自定義
                    version = "1.0",    //固定!
                    methoD = "thing.event.property.post",    //固定!
                };

                // 數據和時間戳
                model.paramS.cpuwd.value = cpuwd;
                model.paramS.cpuwd.time = ConvertDateTimeToInt();
                model.paramS.cpuxh.value = cpuxh;
                model.paramS.cpuxh.time = ConvertDateTimeToInt();

                // 推送內容到特定的 Topic
                client.Thing_Property_Post<TestModel>(model, true);
            }

            Console.ReadKey();
        }
        /// <summary>  
        /// 將c# DateTime時間格式轉換爲Unix時間戳格式  
        /// </summary>  
        /// <param name="time">時間</param>  
        /// <returns>long</returns>  
        public static long ConvertDateTimeToInt()
        {
            System.DateTime time = DateTime.Now;
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000調整爲13位      
            return t;
        }
    }
    public class 事件類
    {
        public void 收到消息(object sender, MqttMsgPublishEventArgs e)
        {
            Console.WriteLine("topic名稱:" + e.Topic);
            Console.WriteLine("接收時間:" + DateTime.Now.ToLongDateString());
            Console.WriteLine("消息內容:\n" + Encoding.ASCII.GetString(e.Message));
        }
        public void 重複收到消息(object sender, MqttMsgPublishedEventArgs e)
        {
            Console.WriteLine("接收時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId + "    Is Published: " + e.IsPublished);
        }
        public void 發佈消息時(object sender, MqttMsgSubscribedEventArgs e)
        {
            Console.WriteLine("向服務器發送了消息");
            Console.WriteLine("發送時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId);
            Console.WriteLine("QOS 爲 :    " + Encoding.UTF8.GetString(e.GrantedQoSLevels));
        }
        public void 發送失敗(object sender, MqttMsgUnsubscribedEventArgs e)
        {
            Console.WriteLine("消息發送失敗 ");
            Console.WriteLine("時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("失敗的消息 MessageId:    " + e.MessageId);
        }
        public void 斷開鏈接(object sender, EventArgs e)
        {
            Console.WriteLine("日。。。鏈接斷開了: " + DateTime.Now.ToLongTimeString());
        }
    }

 

 

 

考慮到有些師弟在看~貼一下部分代碼的解釋

Random random = new Random();
int wd = random.Next(40,60);
簡化寫成
(new Random()).Next(40, 60)

 .Next(,) 生成範圍內的 int 類型數值, .NextDouble() 生成 0<=n<1 的數,double類型。

time是 long int 類型,要填寫 13 位時間戳。不懂請點擊 https://www.jb51.net/article/149152.htm

public int Thing_Property_Post<AlinkModel>(AlinkModel model, bool isToLower = true);

Thing_Property_Post() 方法能夠把屬性上傳到服務器,isToLwer 表示是否轉爲小寫再上傳。

注意:阿里雲IOT json 區分大小寫,因此建議控制檯定義屬性是,標識符使用小寫,客戶端上傳json時,所有轉爲小寫,避免出錯。

三個重載方法

上傳屬性有三個重載方法

        public int Thing_Property_Post<AlinkModel>(AlinkModel model, bool isToLower = true);
        public int Thing_Property_Post(byte[] json);
        public int Thing_Property_Post(string json, bool isToLwer = true);

自定義屬性模型,經過第一個方法能夠直接轉換上傳,省略沒必要要操做。

把 json string 轉byte[] ,能夠經過第二個方法上傳到服務器。必須注意byte[]進制問題!

若是隻有json,不須要自定義模型,則使用第三種方法上傳。

 

接收響應

根據協議,屬性、事件、服務,上傳或下發,另外一方要進行響應。

上面的例子運行後,控制檯並無反應。

由於咱們沒有設置要接收響應。

修改一下訂閱Topic

            // 要訂閱的Topic
            string[] topic = { client.CombineHeadTopic("PubData"),client.thingModel.upTopic.post_reply };

client.thingModel.upTopic.post_reply ,一個Topic地址,因爲接收發布屬性後,接收服務器的響應消息。

thingModel 定義的設備屬性服務事件,發送接收以及響應的Topic。這些下一章說。

服務器響應內容格式

{
  "id": "123",
  "code": 200,
  "data": {}
}

修改後的完整代碼

    class Program
    {
        static void Main(string[] args)
        {
            // 建立鏈接對象
            XFMQTT client = new XFMQTT("a1BiPoNawLI", "Raspberry");
            // 初始化客戶端配置
            client.Init("2NOaBeqXcIzLQEhlJFEfKbWeug0o3m0c", "cn-shanghai");
            // 要訂閱的Topic
            string[] topic = { client.CombineHeadTopic("PubData"),client.thingModel.upTopic.post_reply };

            // 使用自定義的委託事件
            事件類 事件 = new 事件類();
            client.PubEventHandler += 事件.收到消息;
            client.PubedEventHandler += 事件.重複收到消息;
            client.SubedEventHandler += 事件.發佈消息時;
            client.UnSubedEventHandler += 事件.發送失敗;
            client.ConnectionClosedEventHandler += 事件.斷開鏈接;
            //client.add
            // 鏈接服務器
            client.ConnectMqtt(topic);

            while (true)
            {
                Thread.Sleep(1000);

                //模擬數據
                // cpu溫度
                float cpuwd = (float)(new Random()).Next(40, 60) + (float)(new Random()).NextDouble();
                // cpu消耗
                float cpuxh = (float)(new Random()).Next(30, 40) + (float)(new Random()).NextDouble();

                // 模型對象
                TestModel model = new TestModel
                {
                    id = "123456",      //自定義
                    version = "1.0",    //固定!
                    methoD = "thing.event.property.post",    //固定!
                };

                // 數據和時間戳
                model.paramS.cpuwd.value = cpuwd;
                model.paramS.cpuwd.time = ConvertDateTimeToInt();
                model.paramS.cpuxh.value = cpuxh;
                model.paramS.cpuxh.time = ConvertDateTimeToInt();

                // 推送內容到特定的 Topic
                client.Thing_Property_Post<TestModel>(model, true);
            }

            Console.ReadKey();
        }
        /// <summary>  
        /// 將c# DateTime時間格式轉換爲Unix時間戳格式  
        /// </summary>  
        /// <param name="time">時間</param>  
        /// <returns>long</returns>  
        public static long ConvertDateTimeToInt()
        {
            System.DateTime time = DateTime.Now;
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0));
            long t = (time.Ticks - startTime.Ticks) / 10000;   //除10000調整爲13位      
            return t;
        }
    }
    public class 事件類
    {
        public void 收到消息(object sender, MqttMsgPublishEventArgs e)
        {
            Console.WriteLine("topic名稱:" + e.Topic);
            Console.WriteLine("接收時間:" + DateTime.Now.ToLongDateString());
            Console.WriteLine("消息內容:\n" + Encoding.ASCII.GetString(e.Message));
        }
        public void 重複收到消息(object sender, MqttMsgPublishedEventArgs e)
        {
            Console.WriteLine("接收時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId + "    Is Published: " + e.IsPublished);
        }
        public void 發佈消息時(object sender, MqttMsgSubscribedEventArgs e)
        {
            Console.WriteLine("向服務器發送了消息");
            Console.WriteLine("發送時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("消息id: " + e.MessageId);
            Console.WriteLine("QOS 爲 :    " + Encoding.UTF8.GetString(e.GrantedQoSLevels));
        }
        public void 發送失敗(object sender, MqttMsgUnsubscribedEventArgs e)
        {
            Console.WriteLine("消息發送失敗 ");
            Console.WriteLine("時間: " + DateTime.Now.ToLongTimeString());
            Console.WriteLine("失敗的消息 MessageId:    " + e.MessageId);
        }
        public void 斷開鏈接(object sender, EventArgs e)
        {
            Console.WriteLine("日。。。鏈接斷開了: " + DateTime.Now.ToLongTimeString());
        }
    }
View Code

運行程序能夠發現控制檯會接收到服務器響應提示

相關文章
相關標籤/搜索