開發與維運

LoRa溫溼度傳感器通過LinkWAN平臺,接入AIoT物聯網平臺最佳實踐

本文提供LoRa溫溼度傳感器通過Link WAN接入,同時採用阿里雲物聯網平臺實現端到端應用。

背景信息

  • 開通物聯網絡管理平臺完成賬號的註冊之後,使用賬號登錄Link WAN 開通服務。
  • LoRa節點設備接入
  • 搭建與管理網絡參見搭建與管理網絡搭建和管理網絡、創建節點組並添加節點。
  • 配置數據流轉目前數據流轉支持阿里雲物聯網平臺、消息隊列MQ兩種方式,這裡選擇將數據流轉至阿里雲物聯網平臺,詳情請參見數據接入物聯網平臺-1對1
  • 物聯網平臺LoRa節點設備接入本章介紹如何在物聯網平臺開發平臺上進行設備接入的開發。主要的開發內容包括:

    • 項目和產品創建
    • 產品功能定義
    • 平臺腳本開發

本文以一個空氣溫溼度傳感器為例,同時可以配置溫溼度的閾值,在溫溼度超出閾值時上報事件。

創建產品和設備

  1. 登錄物聯網平臺控制檯
  2. 在左側導航欄上選擇設備管理 > 產品,單擊創建產品, 填寫產品信息後單擊完成。詳情請參見數據接入物聯網平臺-1對1
    | 參數 | 描訴 |
產品名稱 可填寫任意名稱
所屬品類 自定義品類
節點類型 直連設備
連網方式 LoRaWAN
入網憑證 從表單選擇,如無可單擊創建憑證
數據格式 透傳/自定義
  1. 為產品添加LoRa設備。在左側導航欄上單擊設備,參見單個創建設備添加設備。說明使用LoRaWAN設備的DevEUI需小寫作為deviceName。

    • 添加完成後,顯示如下,此時設備狀態為未激活
    • 數據流轉已自動同步 產品創建完成後,可在Link WAN裡看到自動同步的數據流轉設置。
      說明 在網管平臺只能查閱,新增終端請移步至物聯網平臺維護。

產品功能定義

產品創建完成之後,需要在平臺上定義產品有哪些功能。功能定義是為了讓平臺能夠理解設備上下行的數據定義,便於上層應用的讀寫。

  1. 在左側導航欄上選擇設備管理 > 產品,單擊產品對應操作欄中的查看
  2. 選擇功能定義 > 編輯草稿,單擊自定義功能 > 添加自定義功能
  3. 添加自定義功能彈框中,功能類型選擇屬性,添加溫溼度屬性。

    • 添加溫度屬性,配置參數如下圖所示。
    • 添加溼度屬性,配置參數如下圖所示。
  4. 功能類型選擇服務,添加溫度溼度閾值,參數配置如下圖所示。
    其中輸入參數設置如下圖所示。
    | 參數名稱 | 標誌符 | 數據類型 | 取值範圍 | 步長 | 單位 |
溫度過高閾值 MaxTemp int32(整數型) -40~55 1 攝氏度/℃
溫度過低閾值 MinTemp int32(整數型) 40~55 1 攝氏度/℃
溼度過高閾值 MaxHumi int32(整數型) 1~100 1 百分比/%
溼度過低閾值 MinHumi int32(整數型) 1~100 1 百分比/%
  1. 功能類型選擇事件,添加溼度過高/過低告警事件。告警輸出參數為當前溼度。
    其中輸出參數設置如下。
  2. 單擊確認,單擊頁面右下方的發佈更新。上述屬性、服務、事件添加完成後,在自定義功能一欄下方可確認添加的結果。

平臺腳本開發

  1. 進入產品數據解析標籤頁,可以添加解析腳本。由於數據是以自定義格式透傳到平臺,所以需要添加腳本來解析自定義協議。
  2. 將下列代碼添加到上圖的腳本編輯區
var ALINK_ID = "12345";
var ALINK_VERSION = "1.1";
var ALINK_PROP_POST_METHOD     = 'thing.event.property.post';
var ALINK_EVENT_TEMPERR_METHOD = 'thing.event.TempError.post';
var ALINK_EVENT_HUMIERR_METHOD = 'thing.event.HumiError.post';
var ALINK_PROP_SET_METHOD      = 'thing.service.property.set';
var ALINK_SERVICE_THSET_METHOD = 'thing.service.SetTempHumiThreshold';
/*
 * 示例數據:
 *  傳入參數 ->
 *      000102 // 共3個字節
 *  輸出結果 ->
 *      {"method":"thing.event.property.post", "id":"12345", "params":{"Temperature":1,"Humidity":2}, "version":"1.1"}
 *  傳入參數 ->
 *      0102 // 共2個字節
 *  輸出結果 ->
 *      {"method":"thing.event.TempError.post","id":"12345","params":{"Temperature":2},"version":"1.1"}
 *  傳入參數 ->
 *      0202 // 共2個字節
 *  輸出結果 ->
 *     {"method":"thing.event.HumiError.post","id":"12345","params":{"Humidity":2},"version":"1.1"}
 */
function rawDataToProtocol(bytes)
{
    var uint8Array = new Uint8Array(bytes.length);
    for (var i = 0; i < bytes.length; i++)
    {
        uint8Array[i] = bytes[i] & 0xff;
    }
    var params = {};
    var jsonMap = {};
    var dataView = new DataView(uint8Array.buffer, 0);
    var cmd = uint8Array[0]; // command
    if (cmd === 0x00)
    {
        params['Temperature']  = dataView.getInt8(1); 
        params['Humidity']     = dataView.getInt8(2); 
        jsonMap['method']  = ALINK_PROP_POST_METHOD;
    }
    else if (cmd == 0x01)
    {
        params['Temperature']  = dataView.getInt8(1); 
        jsonMap['method']  = ALINK_EVENT_TEMPERR_METHOD;
    }
    else if (cmd == 0x02)
    {
        params['Humidity']  = dataView.getInt8(1); 
        jsonMap['method']  = ALINK_EVENT_HUMIERR_METHOD;
    }
    else
    {
        return null;
    }
    jsonMap['version'] = ALINK_VERSION;
    jsonMap['id']      = ALINK_ID; 
    jsonMap['params']  = params;
    return jsonMap;
}
/*
 * 示例數據:
 *  傳入參數 ->
 *      {"method":"thing.service.SetTempHumiThreshold", "id":"12345", "version":"1.1", "params":{"MaxTemp":50, "MinTemp":8, "MaxHumi":90, "MinHumi":10}}
 *  輸出結果 ->
 *      0x5d0a000332085a0a
 */
function protocolToRawData(json)
{
    var id  = json['id'];
    var method  = json['method'];
    var version = json['version'];
    var payloadArray = [];
    // 追加下行幀頭部
    payloadArray = payloadArray.concat(0x5d);
    payloadArray = payloadArray.concat(0x0a);
    payloadArray = payloadArray.concat(0x00);
    if (method == ALINK_SERVICE_THSET_METHOD)
    {
        var params  = json['params'];
        var maxtemp = params['MaxTemp'];
        var mintemp = params['MinTemp'];
        var maxhumi = params['MaxHumi'];
        var minhumi = params['MinHumi'];
        payloadArray = payloadArray.concat(0x03);
        if (maxtemp !== null)
        {
            payloadArray = payloadArray.concat(maxtemp);
        }
        if (mintemp !== null)
        {
            payloadArray = payloadArray.concat(mintemp);
        }
        if (maxhumi !== null)
        {
            payloadArray = payloadArray.concat(maxhumi);
        }
        if (minhumi !== null)
        {
            payloadArray = payloadArray.concat(minhumi);
        }
    }
    return payloadArray;
}
// 以下是部分輔助函數
function buffer_uint8(value)
{
    var uint8Array = new Uint8Array(1);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setUint8(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int16(value)
{
    var uint8Array = new Uint8Array(2);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt16(0, value);
    return [].slice.call(uint8Array);
}
function buffer_int32(value)
{
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setInt32(0, value);
    return [].slice.call(uint8Array);
}
function buffer_float32(value)
{
    var uint8Array = new Uint8Array(4);
    var dv = new DataView(uint8Array.buffer, 0);
    dv.setFloat32(0, value);
    return [].slice.call(uint8Array);
}
  1. 腳本解析下行數據的函數 protocolToRawData 中必須設定輸出結果的起始三個字節(用於指定下行的端口號以及下行消息類型),否則系統會丟掉下行幀。另外,節點實際接收到的數據將不會包含起始的三個字節。
    起始三字節的說明如下表所示。
    | Size(bytes) | LoRa Downlink | 描述 |
1 DFlag 固定為 0x5D
1 FPort 下行端口號
1 DHDR
- 0 表示 “Unconfirmed Data Down”數據幀
- 1 表示 “Confirmed Data Down”數據幀
  1. 示例:0x5D 0x0A 0x00表示:下行幀端口號為10,數據幀為nconfirmed Data Down。
  2. 腳本模擬運行。

    1. 設備上報數據調試。在腳本調試區1裡輸入下面數據,模擬類型選擇設備上報數據後,單擊運行按鈕。

說明 000102 中的 00 表示後面的兩個字節分別表示溫度和溼度,01 表示溫度為1攝氏度,02表示溼度為2%。

  1. 設備接收數據調試。在腳本調試區1裡輸入以下數據,模擬類型選擇設備接收數據後,單擊運行按鈕。
{
    "method": "thing.service.SetTempHumiThreshold",
    "id": "12345",
    "version": "1.1",
    "params": {
        "MaxTemp": 50,
        "MinTemp": 8,
        "MaxHumi": 90,
        "MinHumi": 10
    }
}
  1. 查看腳本調試區2的運行結果如下:
  1. 腳本腳本調試無誤後,單擊提交按鈕提交腳本。

設備在線調試

腳本提交後,可以結合節點測試數據的上下行鏈路是否打通,LoRa節點如何發送以及接收數據請參考各模組廠商的相關手冊。

  1. 節點數據上行。

    1. 上報溫溼度屬性。

      1. 在LoRa節點側選擇輸入十六進制的000102後發送數據。
      2. 從左側導航欄的設備 > 設備列表選擇對應節點,單擊查看
      3. 單擊運行狀態
      4. 確認節點的溼度與溫度信息是否已經上報且設置如下。
    2. 上報溫溼度告警事件。

      • 溫度告警事件上報

        1. 在 LoRa 節點側選擇輸入十六進制的0102 後發送數據。
        2. 設備詳情 > 事件管理中確認溫度告警事件是否已經上報。
      • 溼度告警事件上報

        1. 在LoRa節點側選擇輸入十六進制的0202後發送數據。
        2. 設備詳情 > 事件管理中確認溼度告警事件是否已經上報。
  2. 節點數據下行。

    1. 產品詳情 > 設備開發單擊對應節點的調試按鈕,進入在線調試頁面。
    2. 選擇調試功能為之前添加的溫度溼度閾值,具體格式如下所示,單擊發送指令。
      發送完成後在節點側確認輸出是否是16進制的0332085a0a

說明 對於Class A類型的節點,需要先發送數據才能啟動接收。

固件升級

LoRa節點設備可以通過本地端燒錄方式升級固件,目前不支持網絡在線升級(FUOTA)。

Leave a Reply

Your email address will not be published. Required fields are marked *