日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

3.2 自定義協議驅動開發指導

更新時間:

概述

本文檔指導自定義協議驅動開發人員,了解物聯網設備接入相關知識,并且可以根據設備接入SDK開發驅動,實現設備物模型定義的功能。

1.了解物聯網設備接入

1.1 設備接入概念

設備接入是Link IoT Edge提供的基礎能力,設備接入模塊在Link IoT Edge中稱為驅動(driver)或設備接入驅動。所有連接到Link IoT Edge的設備都需要通過驅動實現接入。

設備接入驅動在Link IoT Edge框架位置如圖所示。

設備接入框架圖

1.2 設備接入驅動

1.2.1 設備接入驅動的功能組成

一個完整的驅動(設備接入模塊)由設備的連接管理、設備的數據(協議)轉換和設備的數據與命令處理三個模塊組成。

1.2.1.1連接管理

指設備與網關建立通信連接。Link IoT Edge不限制建立通信連接的協議,可根據業務需求靈活選擇。

1.2.1.2數據轉換

指設備接入驅動將獲取到的終端設備數據轉換為符合阿里云IoT物模型規范的數據格式,并上報到阿里云IoT Cloud。阿里云物聯網平臺物模型規范請參考物模型

1.2.1.3數據與命令處理

指驅動可以處理云端對于設備的操作請求,并完成對設備的服務調用和處理調用結果,最終將結果返回到阿里云物聯網平臺。

1.2.2 設備接入驅動的開發工作

設備接入驅動是Link IoT Edge中獨立的服務模塊,您可以根據業務協議需求開發自定義設備接入驅動。下圖展示了自定義驅動的功能和數據流向,并指出了開發一個自定義驅動需要做的開發工作。

IoT框架

2.驅動開發

Link IoT Edge提供設備接入SDK(Link Edge Device Access,簡稱LEDA)方便您開發自己的驅動,SDK目前支持C、Node.js、Java和Python四種版本的語言。

2.1 LEDA接口介紹

LEDA支持的四種開發語言詳細內容,請參見CNode.jsJavaPython

雖然SDK版本不同,但提供的功能是一樣的,LEDA接口調用關系如下圖所示:

image

2.2 驅動編碼示例

在驅動開發過程中進行驅動編碼時,需遵循物聯網邊緣計算的驅動編碼規范和步驟。

2.2.1 驅動和設備配置

進行驅動編碼前,需要了解Link IoT Edge的設備信息配置和驅動信息配置相關內容。

2.2.1.1 驅動配置

驅動信息配置在阿里云物聯網平臺進行配置。部署邊緣實例時,驅動配置信息會被部署到邊緣網關,其內容以JSON格式存儲在Link IoT Edge配置中心,可以通過leda_get_driver_info接口獲取。

驅動信息配置為JSON格式:

{
    "json":{
        "ip":"127.0.0.1",
        "port":54321
    }
}

格式參數說明如下:

參數名稱

說明

json

驅動配置的格式為JSON格式配置。配置內容為自定義內容。

驅動配置示例:

image

2.2.1.2 設備配置

設備信息配置在阿里云物聯網平臺控制臺配置。部署邊緣實例時,設備信息配置會被部署到邊緣網關,其內容以JSON格式存儲,可以通過leda_get_device_info接口獲取。

設備信息配置格式定義:

{
    "deviceList": [{
        "custom": {
             "ip":"127.0.0.1",
             "port":22322
        }, // 設備自定義配置
        "productKey": "xxxxxxxxxxx", // 產品ProductKey,在創建產品時生成
        "deviceName": "demo_led",    // 設備DeviceName,在創建設備時設置
    }]
}

設備信息配置參數說明:

配置名稱

配置解釋

deviceList

當前驅動下所有已進行設備配置的設備列表。

custom

設備自定義配置。

productKey

設備所在產品唯一標識符。

deviceName

設備名稱。

實際設備配置示例:

image

2.2.2 驅動代碼示例

完成驅動編碼,可參考以下4個示例。本示例的完整工程源碼請參見Github源碼庫LED設備驅動

2.2.2.1 初始化驅動資源

調用leda_init接口完成資源初始化。

int main(int argc, char** argv)
{
    ...
 
    /* init driver */
    if (LE_SUCCESS != (ret = leda_init(WORKER_THREAD_NUMS)))
    {
        log_e(TAG_NAME_LED_DRIVER, "leda_init failed\n");
        return ret;
    }
 
    ...
 
  return LE_SUCCESS;
}

2.2.2.2 解析驅動配置,完成設備上線

通過調用leda_get_driver_info接口獲取驅動配置,解析設備的連接信息,并根據解析結果連接設備。設備連接成功后,調用leda_get_device_info接口獲取設備配置并解析,根據解析結果驗證設備功能。功能驗證通過后,調用leda_register_and_online_by_device_name接口完成設備注冊并上線到阿里云物聯網平臺

static int online_devices()
{
  ...
 
    /* 獲取驅動和設備配置 */
    size = leda_get_device_info_size();
    if (size >0)
    {
        device_config = (char*)malloc(size);
        if (NULL == device_config)
        {
            log_e(TAG_DEMO_LED, "allocate memory failed\n");
            return LE_ERROR_INVAILD_PARAM;
        }
 
        if (LE_SUCCESS != (ret = leda_get_device_info(device_config, size)))
        {
            log_e(TAG_DEMO_LED, "get device config failed\n");
            return ret;
        }
    }
 
    /* 解析驅動和設備配置 */
    devices = cJSON_Parse(device_config);
    if (NULL == devices)
    {
        log_e(TAG_DEMO_LED, "device config parser failed\n");
        return LE_ERROR_INVAILD_PARAM;
    }
 
    cJSON_ArrayForEach(item, devices)
    {
        if (cJSON_Object == item->type)
        {
            /* 解析配置內容 */
            result      = cJSON_GetObjectItem(item, "productKey");
            productKey  = result->valuestring;
 
            result      = cJSON_GetObjectItem(item, "deviceName");
            deviceName  = result->valuestring;
 
            result      = cJSON_GetObjectItem(item, "custom");
            if (NULL != result)
            {
                log_i(TAG_DEMO_LED, "custom content: %s\n", cJSON_Print(result));
            }
 
            /* 注冊并上線設備 */
            device_cb.get_properties_cb            = get_properties_callback_cb;
            device_cb.set_properties_cb            = set_properties_callback_cb;
            device_cb.call_service_cb              = call_service_callback_cb;
            device_cb.service_output_max_count     = 5;
 
            dev_handle = leda_register_and_online_by_device_name(productKey, deviceName, &device_cb, NULL);
            if (dev_handle < 0)
            {
                log_e(TAG_DEMO_LED, "product:%s device:%s register failed\n", productKey, deviceName);
                continue;
            }
 
            g_dev_handle = dev_handle;
            log_i(TAG_DEMO_LED, "product:%s device:%s register success\n", productKey, deviceName);
        }
    }
 
  ...
 
    return LE_SUCCESS;
}

2.2.2.3 上報數據

將收到的設備數據轉換為阿里云IoT物模型格式并上報到物聯網平臺,調用leda_report_properties接口上報設備屬性數據,調用leda_report_event接口上報設備事件。

/* 上報數據 */
while (1)
{
    /* 上報屬性 */
    leda_device_data_t dev_proper_data[1] =
    {
        {
            .type  = LEDA_TYPE_INT,
            .key   = {"temperature"},
            .value = {0}
        }
    };
    sprintf(dev_proper_data[0].value, "%d", g_dev_temperature);
    leda_report_properties(g_dev_handle, dev_proper_data, 1);
 
    /* 上報事件 */
    if (g_dev_temperature > 50)
    {
        leda_device_data_t dev_event_data[1] =
        {
            {
                .type  = LEDA_TYPE_INT,
                .key   = {"temperature"},
                .value = {0}
            }
        };
        sprintf(dev_event_data[0].value, "%d", g_dev_temperature);
        leda_report_event(g_dev_handle, "high_temperature", dev_event_data, 1);
    }
 
    sleep(5);
}

2.2.2.4 處理云端服務請求

實現服務請求的三個回調函數如下所示。

get接口:處理獲取設備屬性的請求。

set接口:處理設置設備屬性的請求。

service接口:處理調用設備自定義方法的請求。

static int get_properties_callback_cb(device_handle_t device_handle,
                               leda_device_data_t properties[],
                               int properties_count,
                               void *usr_data)
{
    ...
 
    return ret;
}
 
static int set_properties_callback_cb(device_handle_t device_handle,
                               const leda_device_data_t properties[],
                               int properties_count,
                               void *usr_data)
{
    ...
 
    return ret;
}
 
static int call_service_callback_cb(device_handle_t device_handle,
                               const char *service_name,
                               const leda_device_data_t data[],
                               int data_count,
                               leda_device_data_t output_data[],
                               void *usr_data)
{
    ...
 
    return ret;
}

2.3 驅動產出方式

2.3.1 驅動依賴注意事項

設備接入驅動根據協議和業務場景的不同,可能會涉及第三方庫依賴。Link IoT Edge針對開發設備接入驅動所用不同開發語言,分別制定了第三方庫依賴規則。

  • C版本SDK:C語言屬于編譯型語言,如果編譯目標環境和運行環境不一致,則很可能導致不可運行。所以對于使用設備接入C版本SDK開發驅動,需要保證開發編譯目標環境和運行環境相同。 驅動包中包含驅動程序和依賴動態庫。如果該驅動依賴于第三方庫,則需要將動態庫和驅動程序一起打包生成最終驅動程序包。

  • Node.js版本SDK:使用設備接入SDK Node.js版本開發驅動時,若依賴第三方庫,需要到Link IoT Edge運行環境上開發驅動,并在驅動目錄中使用如下命令安裝依賴。

npm install 第三方庫名
  • Python版本SDK:使用設備接入SDK Python版本開發驅動時,若依賴第三方庫,需要到Link IoT Edge運行環境上開發驅動,并在驅動目錄中使用如下命令安裝依賴。

pip3 install -t . 第三方庫名

2.3.2 驅動打包方式

基于Link IoT Edge提供的SDK開發驅動并完成調試后,需將產物打包為.zip包,并確保驅動Binary或index源文件在.zip包第一級目錄。

每個版本SDK開發的驅動在打包時,有不同的打包規則。

  • 基于C SDK開發的驅動對于C語言開發的驅動,驅動包中包含驅動程序和驅動依賴的動態庫。如果驅動程序包含依賴庫,則需要將依賴庫放置指定的位置,即在驅動程序當前路徑下的lib文件夾下。具體操作步驟如下:

    1. 規定驅動程序需命名為main。

    2. 在main當前路徑下創建lib文件夾。

    3. 將main依賴的動態庫全部拷貝到lib文件夾下。

    4. 使用zip命令對當前路徑下的main和lib進行壓縮處理生成zip包。

zip -r your_driver_name.zip main lib
  • 基于Python SDK開發的驅動包文件中須包含index.py,并且在該文件中定義handler函數。驅動是一個在函數計算應用引擎中持續運行的函數,所以在驅動包中須包含index.py文件,并且在該文件中定義handler函數。 驅動運行時,會加載index.py文件。而該文件中,函數計算應用定義的handler函數是不會被調用,因此驅動代碼須放在handler函數外,保證加載index.py文件時能直接執行。詳情請參考Python版本SDK

  • 基于Node.js SDK開發的驅動包文件中須包含index.js,并且在該文件中定義handler函數。 驅動運行時,會加載index.js文件。而該文件中,函數計算應用定義的handler函數是不會被調用,因此驅動代碼須放在handler函數外,保證加載index.js文件時能直接執行。詳情請參考Nodejs版本SDK

2.4 驅動使用示例

2.4.1 上傳及發布驅動

  • 在SI集成工作臺si.iot.aliyun.com上,選擇邊緣接入->驅動管理,選擇新增驅動

    根據提示設置參數,需要注意的是通信協議類型要選擇【自定義】

imageimageimage

  • 上傳已完成編譯并打包的led_driver.zip文件。

  • 完成參數的設置并上傳成功驅動文件后,單擊確定。您可以在自研驅動列表中看到剛剛創建的驅動

2.4.2分配驅動和設備到邊緣實例

2.4.2.1 添加驅動到邊緣實例

  • 登錄SI集成工作臺si.iot.aliyun.com,在網關管理設備集成頁面,點擊網關右側的設置圖標,首先,在彈出菜單中選擇添加協議

image
  • 然后,在下拉選擇的協議列表中選擇“DemoDriver”,選擇“確定”。

image

2.4.2.2 新建設備

  • 如下圖所示,通過點擊通道右側的“設置”圖標,選擇“新建設備”

image
  • 在彈出的新建設備頁面中按照如下方式選擇刷卡門禁

image
  • 點擊確定按鈕即可完成設備創建,創建好的設備如下如所示:

image

2.4.3 部署邊緣實例

  • 實例詳情頁面,右上角單擊部署,部署邊緣實例。部署成功后邊緣實例名稱后顯示部署成功

image

2.4.4 查看驅動日志

在邊緣網關宿主機命令行中通過docker命令進入LE網關運行環境,命令如下:

sudo docker exec -it $(sudo docker ps | grep k8s_linkedge  | awk '{print $1}') bash

進入網關容器內之后可以在本地查看驅動日志。

a. 通過./fctl show命令,可以查看到部署驅動的具體位置。

cd /linkedge/gateway/build/bin/
./fctl show

系統顯示類似如下圖所示:圖1

參數說明:

字段名稱

字段解釋

DriverName

驅動名稱,該名稱為在上傳及發布驅動步驟中設置的驅動名稱。

CodePath

驅動部署到邊緣網關中的位置路徑。

Process PID

驅動啟動后的進程ID。

b. 驅動在運行過程中會產生運行日志,通過查看運行日志可以了解驅動運行狀態,每個自定義驅動生成的日志文件統一放在/linkedge/run/logger/fc-base路徑下。每個驅動日志文件路徑為/linkedge/run/logger/fc-base/xxxx/log_xxxx.txt。

說明驅動日志文件路徑中的xxxx為在上傳驅動時填寫的名稱。

cd /linkedge/run/logger/fc-base/demo_driver && ls -l

詳情如下圖所示:詳情

驅動運行日志可以查看大部分驅動的運行狀態,但是有時還需要查看其它日志配合了解當前驅動的運行情況,例如設備上線異常時可以查看dimu日志,日志文件路徑為/linkedge/run/logger/dimu/log_xxxxx.txt。

cd /linkedge/run/logger/dimu
ls -l

詳情如下圖所示:詳情2

設備上線成功后,如果設備數據上報有異常,則可以查看cloud_proxy日志。cloud_proxy產生的運行日志文件路徑格式為/linkedge/run/logger/cloud-proxy/log_xxxxx.txt。

cd /linkedge/run/logger/cloud-proxy
ls -l

詳情如下圖所示:詳情3

2.5 驅動調試方式

2.5.1 云端在線調試

如果設備上線成功,則可以使用阿里云物聯網平臺在線調試功能調試驅動和設備,該功能頁面還可以實時查看設備上報的數據信息,也可以觸發對設備服務的調用請求。

a.物聯網平臺控制臺,選擇監控運維 > 在線調試,在在線調試頁面,選擇調試產品和調試設備。

b.選擇調試設備待調功能和服務,進行調試,并查看設備實時運行日志在線調試

2.5.2 邊緣端替換驅動

如果在驅動調試過程中發現問題,需要修改驅動代碼重新生成新的驅動進行調試,這時只需要在本地替換修改編譯后的驅動即可。

a. 找到驅動的位置。可以通過fctl命令進行查找,具體字段解釋查看調試信息。

cd /linkedge/gateway/build/bin/
./fctl show
詳情3

b. 根據CodePath找到驅動所在位置路徑,完成替換。

c. 根據Process PID得到驅動進程ID,使用kill -9 Pid命令重新啟動驅動。

kill -9 Pid #Pid為驅動進程ID,即通過fctl命令查看得到的Process PID