為了讓開(kāi)發(fā)者在沒(méi)有硬件的情況下仍能體驗(yàn)平臺(tái)的透?jìng)鲄f(xié)議功能,本示例在Linux系統(tǒng)下實(shí)現(xiàn)一個(gè)虛擬的光照度探測(cè)器。

背景信息

虛擬的光照度探測(cè)器的主要功能如下。

  • 光照度值定期5s上報(bào)

    定義屬性lux標(biāo)識(shí)當(dāng)前光照度值,類型為整型,取值范圍0~100。

  • 當(dāng)光照值超過(guò)設(shè)定閾值時(shí)觸發(fā)告警事件

    定義光照過(guò)高告警事件OverLuxAlarm,事件參數(shù)為當(dāng)前光照值lux。

  • 通過(guò)服務(wù)調(diào)用設(shè)置告警閾值

    定義異步服務(wù)SetAlarmThreshold,服務(wù)的入?yún)?span id="z68uejxpaoma" class="keyword parmname" id="parmname-gd4-1c9-kuv">threshold,整形,表示告警閾值。

操作步驟

  1. 創(chuàng)建光照度探測(cè)器產(chǎn)品。
    數(shù)據(jù)格式配置為透?jìng)?自定義格式。
    定義屬性
  2. 進(jìn)行產(chǎn)品功能自定義。
    • 定義屬性lux標(biāo)識(shí)當(dāng)前光照度值,類型為整型,取值范圍0~100。
      定義屬性
    • 定義異步服務(wù)SetAlarmThreshold,服務(wù)入?yún)閠hreshold,類型為整形,取值范圍0 ~ 100。表示告警閾值。
      定義服務(wù)
    • 定義光照過(guò)高告警事件OverLuxAlarm,事件參數(shù)為當(dāng)前光照值lux。
      定義事件

    定義完,如下圖自定義功能中所示。


    完成自定義功能
  3. 添加測(cè)試設(shè)備。

    新增測(cè)試設(shè)備
  4. 生成腳本。
    1. 設(shè)備端開(kāi)發(fā)頁(yè)簽中,單擊數(shù)據(jù)解析中的編輯腳本

      數(shù)據(jù)解析
    2. 單擊自動(dòng)生成腳本

      編輯腳本
      腳本生成好之后需要進(jìn)行簡(jiǎn)單驗(yàn)證之后才能提交生效。

業(yè)務(wù)邏輯開(kāi)發(fā)

  • 屬性定時(shí)上報(bào)
    實(shí)現(xiàn)userHandler函數(shù),放在main函數(shù)的while(1)內(nèi)調(diào)用。
    void userHandler(void)
    {
        Uint8_t lux;
        static Uint32_t last, now;
        sdk_global_t *hsdk = (sdk_global_t *)getSdkObjHandle();
    
        /* 采集光照度的值,這里隨機(jī)生成 */
        lux = rand() % 101;  // 取值0~100
        now = hsdk->jiffies;
        if (now - last >= 5000)
        {
            last = now;
            boneSet_lux(lux);   /* 調(diào)用設(shè)置lux的API */
            bonePostProp();     /* 上報(bào) */
        }
    }
    
    Int32_t main(Int32_t argc, char *argv[])
    {
        // 此處省略其他代碼
    
        while (1)
        {
            boneSdkRun();
    
            userHandler();
    
            usleep(100 * 1000);
        }
    						

    重新將代碼編譯運(yùn)行之后可以到云端查看屬性的上報(bào)日志信息如下。說(shuō)明:由于使用的軟件定時(shí)器不是很準(zhǔn),上報(bào)的時(shí)間間隔并非是嚴(yán)格的5s。


    設(shè)置屬性
  • 光照度過(guò)高告警上報(bào)
    默認(rèn)閾值為99,當(dāng)超過(guò)該值時(shí)會(huì)觸發(fā)光照度過(guò)高告警。
    Uint8_t threshold = 99;    /* 告警閾值 */
    
    void userHandler(void)
    {
        Uint8_t lux;
        static Uint32_t last1, last2, now;
        sdk_global_t *hsdk = (sdk_global_t *)getSdkObjHandle();
    
        /* 采集光照度的值,這里隨機(jī)生成 */
        lux = rand() % 101;  // 取值0~100
        now = hsdk->jiffies;
    
        if ((lux > threshold) && (now - last1) > 2000)
        {
            /* 上報(bào)事件,為了避免頻繁上報(bào),這里約束事件上報(bào)間隔最短2s */
            eo_OverLuxAlarm_t oarg;
    
            oarg.a_lux = lux;
            boneEvntPost_OverLuxAlarm(&oarg);   /* 調(diào)用光照過(guò)高告警事件API */
    
            last1 = now;
        }
    
        if (now - last2 >= 5000)
        {
            last2 = now;
            boneSet_lux(lux);   /* 調(diào)用設(shè)置lux的API */
            bonePostProp();     /* 上報(bào) */
        }   
    
    }
    						
    編譯執(zhí)行后,在云端收到當(dāng)告警信息如下:
    告警管理
  • 云端修改告警閾值

    通過(guò)云端修改設(shè)備上的告警閾值,需要在服務(wù)處理接口中添加自己的邏輯代碼。

    extern Uint8_t threshold;
    
    static Int32_t boneServCall_SetAlarmThreshold(Uint32_t id, Uint8_t *data, Uint16_t length)
    {
        Uint8_t len = 0;
        Uint8_t buffer[64] = {0};
        si_SetAlarmThreshold_t *iarg;
        BONE_UNUSED(len);
        BONE_UNUSED(buffer);
    
        // 1. 解析入?yún)ⅲ](méi)有則忽略)
        iarg = (si_SetAlarmThreshold_t*)data;
    
        // 2. 處理入?yún)ⅲ](méi)有則忽略)
        LOG_DBG("threshold = %d\n", iarg->a_threshold);
        threshold = iarg->a_threshold;    // 添加的處理代碼
    
        // 3. 構(gòu)造出參(沒(méi)有則忽略)
    
        // 4. service回復(fù)
        return BONE_SUCCESS;
    }
    					

    編譯后運(yùn)行,通過(guò)云端調(diào)用服務(wù)設(shè)置告警閾值。

    設(shè)備端接收日志:


    設(shè)備端日志

    在云端查看事件日志,光照度閾值大于89時(shí)均上報(bào)了事件。


    設(shè)備事件管理

至此,基于透?jìng)鲄f(xié)議的示例已經(jīng)完成,您可以繼續(xù)在此平臺(tái)上的開(kāi)發(fā)之旅。