阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4. 设备上报属性
設(shè)備自身 CPU 溫度、電源輸入電壓、內(nèi)存使用率等,以及接入到設(shè)備的傳感器如溫度傳感器、光敏傳感器等,這些硬件的數(shù)據(jù)輸出即是?屬性?。
設(shè)備將這些硬件的數(shù)據(jù)上傳到阿里云物聯(lián)網(wǎng)平臺(tái),實(shí)時(shí)顯示這些設(shè)備的狀態(tài)和實(shí)測(cè)數(shù)據(jù),這個(gè)過(guò)程是?上傳設(shè)備屬性?。
1)定義物模型
在阿里云物聯(lián)網(wǎng)控制臺(tái),點(diǎn)擊?產(chǎn)品?->?功能定義?->?添加自定義功能
填入一下內(nèi)容:
再定義一個(gè)屬性:
功能類(lèi)型:屬性功能名稱(chēng): 格力空調(diào)溫度
標(biāo)識(shí)符: gree_temperature
數(shù)據(jù)類(lèi)型: float (單精度浮點(diǎn)型)
取值范圍:0-35
步長(zhǎng): 0.1
單位: 攝氏度 / °C
讀寫(xiě)類(lèi)型:讀寫(xiě)
注意的是,表示符是區(qū)分大小寫(xiě)的,相當(dāng)于 C# 中的變量,筆者這里建議統(tǒng)一使用小寫(xiě),具體原因后面說(shuō)明。
注意:讀寫(xiě)類(lèi)型,一個(gè)只讀、一個(gè)讀寫(xiě)。
2)編寫(xiě)模型
前面說(shuō)過(guò), Alink json 是阿里云定義具有一定格式的 Json ,
因此這些屬性數(shù)據(jù)是以 Json 形式上傳。在 C# 中,可以通過(guò) 類(lèi) 快速生成 Json 。
| id | string | 消息ID號(hào),在這個(gè)設(shè)備的生涯中,ID應(yīng)當(dāng)是唯一的。可以使用時(shí)間戳或guid |
| version | string | 協(xié)議版本號(hào),目前協(xié)議版本號(hào)為1.0。固定 "1.0" 即可 |
| params | Object | 屬性數(shù)據(jù),里面包含多個(gè)屬性對(duì)象,每個(gè)屬性對(duì)象包含上報(bào)時(shí)間(time)和上報(bào)的值(value)。 |
| time | long | 屬性上報(bào)時(shí)間。 |
| value | object | 上報(bào)的屬性值。 |
| method | string | 固定取值?thing.event.property.post |
那么,我們要編寫(xiě)一個(gè)類(lèi),存儲(chǔ)信息,然后轉(zhuǎn)為 Alink json 上傳到阿里云物聯(lián)網(wǎng)服務(wù)器。在編寫(xiě)這個(gè)模型前,預(yù)覽要生成的 Alink json :
{"id": "123456789",
"version": "1.0",
"params": {
"cpu_temperature": {
"value": 58.6,
"time": 1524448722000
},
"gree_temperature": {
"value": 26.6,
"time": 1524448722000
}
},
"method": "thing.event.property.post"
}
我們只需關(guān)注?params?部分的編寫(xiě)即可。
在控制臺(tái)程序中,新建一個(gè)類(lèi)?TestModel。
public class TestModel{
public string id { get { return DateTime.Now.Ticks.ToString(); } set { } }
public string version { get { return "1.0"; } set { } }
public Params
這樣定義后,我們使用時(shí),只需定義 params 部分即可, id、version等,不需要自己動(dòng)態(tài)取值,做重復(fù)勞動(dòng)。
上面有個(gè)?@params?,這是因?yàn)?params 是 C# 的關(guān)鍵字,命名字段時(shí)為了取消沖突所以加個(gè)?@。
根據(jù)我們?cè)诎⒗镌莆锫?lián)網(wǎng)控制臺(tái)定義的?屬性?,繼續(xù)補(bǔ)充內(nèi)容:
public class TestModel{
public string id { get { return DateTime.Now.Ticks.ToString(); } set { } }
public string version { get { return "1.0"; } set { } }
public Params @params { get; set; }
public class Params
{
public Cpu_temperature cpu_temperature { get; set; }
public Gree_temperature gree_temperature { get; set; }
public class Cpu_temperature
{
public float value{ get; set; }
public long time { get; set; }
}
public class Gree_temperature
{
public float value { get; set; }
public long time { get; set; }
}
}
public string @method { get { return "thing.event.property.post"; } set { } }
}
問(wèn)題是,這樣寫(xiě)還不行,因?yàn)檫€沒(méi)有給 TestModel 里的類(lèi)進(jìn)行實(shí)例化。
我們可以利用 構(gòu)造函數(shù) 對(duì)里面的引用類(lèi)型進(jìn)行實(shí)例化,當(dāng)然亦可編寫(xiě)依賴(lài)注入容器。。
{
public string id { get { return DateTime.Now.Ticks.ToString(); } set { } }
public string version { get { return "1.0"; } set { } }
public Params @params { get; set; }
public TestModel()
{
@params = new Params();
}
public class Params
{
public Cpu_temperature cpu_temperature { get; set; }
public Gree_temperature gree_temperature { get; set; }
public Params()
{
cpu_temperature = new Cpu_temperature();
gree_temperature = new Gree_temperature();
}
public class Cpu_temperature
{
public float value{ get; set; }
public long time { get; set; }
}
public class Gree_temperature
{
public float value { get; set; }
public long time { get; set; }
}
}
public string method { get { return "thing.event.property.post"; } set { } }
}
3)上傳設(shè)備屬性數(shù)據(jù)
編寫(xiě)控制臺(tái)程序,引入 CZGL.AliIoTClient ,編寫(xiě)基礎(chǔ)代碼(請(qǐng)?zhí)鎿Q DeviceOptions 的信息):
static AliIoTClientJson client;static void Main(string[] args)
{
再 Program 類(lèi)中,編寫(xiě)一個(gè)方法用來(lái)收集屬性數(shù)據(jù)、上傳屬性數(shù)據(jù):
public static void ToServer(){
啟動(dòng)控制臺(tái)應(yīng)用,在阿里云物聯(lián)網(wǎng)控制臺(tái),打開(kāi)設(shè)備,點(diǎn)擊 運(yùn)行狀態(tài) ,即可看到上傳的屬性數(shù)據(jù)。 文章后面會(huì)詳細(xì)說(shuō)明 CZGL.AliIoTClient 關(guān)于屬性上傳的具體情況。
當(dāng)然,這樣的數(shù)據(jù)只是固定賦值的,這里只是演示,具體數(shù)據(jù)需要開(kāi)發(fā)者采集。下面給出一些模擬數(shù)據(jù)的方法。
4)模擬數(shù)據(jù)
筆者編寫(xiě)了三個(gè)數(shù)據(jù)模擬方法:
不需要理會(huì)里面是怎么寫(xiě)的,僅是個(gè)模擬數(shù)據(jù)的工具而已,你也可以自己編寫(xiě)相應(yīng)的模擬數(shù)據(jù)方法。 里面有四個(gè)參數(shù),對(duì)應(yīng):原始值、最小值、最大值、波動(dòng)范圍。
int 模擬數(shù)據(jù)
range 是指每次生成 [0,range] 范圍的增/減量,
例如 初始值 56 ,?range = 2?,那么可能 56±0 或 56±1 或 56±2 , 是增還是減,是隨機(jī)的。但是設(shè)置 min 、 max 后,最后生成的值會(huì)在此范圍內(nèi)波動(dòng)。
float、double 模擬數(shù)據(jù)
對(duì)應(yīng) float、double,range 的值越大,波動(dòng)范圍越小。默認(rèn)?range = 8,大概就是每次 0.1 的波動(dòng)范圍。
其中,float 小數(shù)保留兩位, double 小數(shù)保留 4 位,
需要更高或減少小數(shù)位數(shù),修改一下?...ToString("#0.0000")
模擬屬性數(shù)據(jù)
接下來(lái)我們模擬一下兩個(gè)屬性的數(shù)據(jù)。
在 Program 中定義兩個(gè)變量存儲(chǔ) cpu 和 空調(diào) 數(shù)據(jù)。
static float cpu_temperature = 50.0F;static float gree_temperature = 26.0F;
修改 ToServer() 方法
public static void ToServer(){
在 Main() 方法里增加代碼:
// 定時(shí)上傳數(shù)據(jù)while (true){ ? ToServer();
Thread.Sleep(1000);
}
至此,已經(jīng)基本完成。
完整代碼如下:
class Program{
static AliIoTClientJson client;
static void Main(string[] args)
{
運(yùn)行控制臺(tái)程序,然后打開(kāi)阿里云物聯(lián)網(wǎng)控制臺(tái),查看設(shè)備的運(yùn)行狀態(tài),打開(kāi)?自動(dòng)刷新?,查看數(shù)據(jù)變化。
如果你覺(jué)得每次波動(dòng)得范圍太大,可以把 range 改大一些,如果你覺(jué)得數(shù)據(jù)不穩(wěn)定,
可以把 min - max 的范圍改小一些,模擬的數(shù)據(jù)值將在此范圍波動(dòng)。
5)設(shè)備屬性 - CZGL.AliIoTClient
首先要說(shuō)明,產(chǎn)品創(chuàng)建前,需要設(shè)置為 Alinkjson/透?jìng)?產(chǎn)品,
因此 CZGL.AliIoTClient 設(shè)置了兩個(gè)客戶(hù)端類(lèi)。
| AliIoTClientJson | 以Alink json形式上傳數(shù)據(jù) |
| AliIoTClientBinary | 以透?jìng)餍问缴蟼鲾?shù)據(jù) |
這兩個(gè)類(lèi),僅在 屬性、事件、服務(wù) 三個(gè)功能中數(shù)據(jù)上傳形式有差別,連接服務(wù)器、普通Topic等其它數(shù)據(jù)的使用是完全一致的。
一個(gè)產(chǎn)品只能定義一種上傳數(shù)據(jù)的形式。
CZGL.AliIoTClient 中上傳屬性的方法(Alink json):
獲取 UNIX 時(shí)間:?由于阿里云要求上傳的屬性數(shù)據(jù)等,要帶上 Unix 時(shí)間,所以筆者一并寫(xiě)在 CZGL.AliIoTClient 了。
public static long GetUnixTime()使用示例參考上面的過(guò)程。
透?jìng)?br />如果你想使用透?jìng)?#xff0c;則使用 AliIoTClientBinary 類(lèi),
6)關(guān)于透?jìng)?/h2>
透?jìng)饕远M(jìn)制報(bào)文形式上傳,例如 0x020000007b00 ,這里是 16 進(jìn)制,每?jī)晌灰粋€(gè)字節(jié)。
如果是 2進(jìn)制 ,則是 8位 一個(gè)字節(jié)。
透?jìng)餍枰诎⒗镌莆锫?lián)網(wǎng)控制臺(tái)創(chuàng)建 透?jìng)?產(chǎn)品后,設(shè)置腳本,將透?jìng)鲾?shù)據(jù) 轉(zhuǎn)為 Alink json。
透?jìng)鲾?shù)據(jù)是自定義的,以字節(jié)為單位,其中有5個(gè)字節(jié)為特定字節(jié),以字節(jié)位進(jìn)行拆分的。
記住,是以字節(jié)為單位。
透?jìng)鲾?shù)據(jù)格式標(biāo)準(zhǔn):
| 幀類(lèi)型 | 1字節(jié) |
| 請(qǐng)求ID | 4字節(jié) |
| 屬性數(shù)據(jù) | N個(gè)字節(jié) |
幀類(lèi)型:
| 0x00 | 屬性上報(bào) |
| 0x01 | 屬性設(shè)置 |
| 0x02 | 上報(bào)數(shù)據(jù)返回結(jié)果 |
| 0x03 | 屬性設(shè)置設(shè)備返回結(jié)果 |
| 0xff | 未知的命令 |
**舉例說(shuō)明 **
很多人是直接把 10進(jìn)制 或 16進(jìn)制 直接轉(zhuǎn)換成 2進(jìn)制 。
例如 0x020000007b00,轉(zhuǎn)為 2進(jìn)制 :100000000000000000000000000111101100000000。 但是這樣是錯(cuò)誤的。
以上面 cpu 和 空調(diào)溫度 舉例,要上傳屬性數(shù)據(jù),幀類(lèi)型為 0x00。
| cpu_temperature | 56 | 38 | 00111000 | 00 11 10 00 |
| gree_temperature | 26 | 1a | 00011010 | 00 01 10 10 |
應(yīng)當(dāng)這樣拆分和設(shè)置值:
| 進(jìn)制表示 | 無(wú) | 0x | 無(wú) |
| 幀類(lèi)型 | 1字節(jié) | 00 | 00000000 |
| ID | 4字節(jié) | 00 00 00 7b | 00000000 00000000 00000000 01111011 |
| cpu_temperature | 1 字節(jié) | 38 | 00111000 |
| gree_temperature | 1 字節(jié) | 1a | 00011010 |
16進(jìn)制數(shù)據(jù):
0x000000007b381a
2進(jìn)制數(shù)據(jù):
00000000000000000000000000000000011110110011100000011010
將 16進(jìn)制 或 2進(jìn)制 的數(shù)據(jù)存儲(chǔ)到 byte[] 變量中,切記要強(qiáng)制轉(zhuǎn)換。 存儲(chǔ)時(shí),一個(gè) byte 為一個(gè)字節(jié),M個(gè)字節(jié),則 byte[M]。
存儲(chǔ):
使用 16進(jìn)制 存儲(chǔ)透?jìng)鲾?shù)據(jù),2進(jìn)制弄不來(lái)的。?
有些同學(xué)非要用 2進(jìn)制 存儲(chǔ),反正我是弄不來(lái),用 二進(jìn)制?數(shù)值?存儲(chǔ),這個(gè)觸發(fā)我的知識(shí)盲區(qū)了。
示例(僅對(duì) AliIoTClientBinary 客戶(hù)端有效):
// 存儲(chǔ)透?jìng)鲾?shù)據(jù)byte[] b = new byte[7];
b[0] = 0x00
如果上報(bào)屬性,要求?請(qǐng)輸入二進(jìn)制數(shù)據(jù)Base64編碼后的字符串,可以使用
byte[] b = new byte[7];b[0] = 0x00
透?jìng)鲾?shù)據(jù)的坑很多,這里 CZGL.AliIoTClient 只提供如何處理數(shù)據(jù)和上傳數(shù)據(jù),云端的腳本解析請(qǐng)參考
https://help.aliyun.com/document_detail/114621.html?spm=a2c4g.11186623.2.13.209b65b9Q9z0Nx#concept-185365
7)后續(xù)說(shuō)明
其實(shí),每次上傳服務(wù)器都會(huì)作出響應(yīng),CZGL.AliIoTClient 默認(rèn)不接收這些響應(yīng)信息。
你可以使用?OpenPropertyPostReply()?接收設(shè)備屬性上傳后服務(wù)器的響應(yīng),應(yīng)當(dāng)在連接服務(wù)器前使用此方法
使用?Close.PropertyPostReply()?取消接收設(shè)備屬性上傳后服務(wù)器的響應(yīng)。
示例:
? ? ? ? ? ?client.ClosePropertyPostReply(); ? ? ? ? ? ?// 連接服務(wù)器? ? ? ? ? ?client.ConnectIoT(topics, null, 60);
上傳屬性數(shù)據(jù),可以分開(kāi)上傳,不需要每次都要上傳全部的屬性。需要更新哪個(gè)屬性,就上傳這個(gè)屬性。
原文地址:https://www.cnblogs.com/whuanle/p/10994694.html
.NET社區(qū)新聞,深度好文,歡迎訪(fǎng)問(wèn)公眾號(hào)文章匯總?http://www.csharpkit.com?
總結(jié)
以上是生活随笔為你收集整理的阿里云物联网 .NET Core 客户端 | CZGL.AliIoTClient:4. 设备上报属性的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: WCF服务端的.NET Core支持项目
- 下一篇: Docker最全教程之MySQL容器化