国产无码免费,人妻口爆,国产V在线,99中文精品7,国产成人无码AA精品一,制度丝袜诱惑av,久久99免费麻辣视频,蜜臀久久99精品久久久久久酒店
        訂閱
        糾錯
        加入自媒體

        一文教你如何利用鴻蒙OS實現智慧家居·LOT上云項目

        2021-06-24 13:39
        一口Linux
        關注

        三、軟件編寫

        我們使用的鴻蒙OS源碼,已經包含了MQTT等常用的模塊,在示例工程中可以方便的查找。這里先簡單講一下目錄結構,熟悉一下整個鴻蒙OS在源碼框架上的細節。

        這里使用的鴻蒙源碼工程,由HPM包管理器獲取,具體源碼結構如下:

        我們列一張表,看看每一個文件夾具體承擔了哪些職能:

        文件名稱描述applicationsBearPi-HM_Nano開發板應用案例base系統的基礎服務,主要使用DFX子系統、啟動文件、硬件適配接口等kernel內核子系統ohos_bundles廠家提供的一些組件和服務third_party第三方組件foundation系統服務框架子系統、WAN開發headers存放main頭文件src存放 main源文件utils公共基礎庫testXTS認證子系統vendor硬件抽象層build編譯構建子系統out存放編譯文件bin存放二進制文件

        適合本文項目的代碼示例,在applications文件夾,具體目錄為:applicationsBearPiBearPi-HM_NanosampleD6_iot_cloud_oc。這里列一下目錄文件結構:

        文件名稱描述E53_IA1.c擴展板驅動oc_mqtt_profile_package.c打包和配置MQTT數據oc_mqtt.cMQTT連接服務wifi_connet.cwifi連接服務iot_cloud_oc_sample.c業務邏輯代碼

        我們主要要用到的API如下,具體實現的細節,可以到源文件里面去閱讀。可以分為初始化和數據上傳兩個部分。

        1. 初始化1)設備信息

        void device_info_init(char *client_id, char * username, char *password);

        設置設備信息,在調用oc_mqtt_init()前要先設置設備信息

        參數描述無無返回描述0成功-1獲得設備信息失敗-2mqtt 客戶端初始化失敗2)華為IoT平臺 初始化

        int oc_mqtt_init(void);

        華為IoT平臺初始化函數,需要在使用 華為IoT平臺 功能前調用。

        參數描述無無返回描述0成功-1獲得設備信息失敗-2mqtt 客戶端初始化失敗3)設置命令響應函數

        void oc_set_cmd_rsp_cb(void(*cmd_rsp_cb)(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size));

        設置命令響應回調函數。

        參數描述recv_data接收到的數據recv_size數據的長度resp_data響應數據resp_size響應數據的長度返回描述無無2. 數據上傳1)設備消息上報

        int oc_mqtt_profile_msgup(char *deviceid,oc_mqtt_profile_msgup_t *payload);

        是指設備無法按照產品模型中定義的屬性格式進行數據上報時,可調用此接口將設備的自定義數據上報給平臺,平臺將設備上報的消息轉發給應用服務器或華為云其他云服務上進行存儲和處理。

        參數描述deviceid設備idpayload要上傳的消息返回描述0上傳成功1上傳失敗2)設備上報屬性數據

        int oc_mqtt_profile_propertyreport(char *deviceid,oc_mqtt_profile_service_t *payload);

        用于設備按產品模型中定義的格式將屬性數據上報給平臺。

        參數描述deviceid設備idpayload要上傳的消息返回描述0上傳成功1上傳失敗

        屬性上報和消息上報的區別,請查看消息通信說明

        3)網關批量上報屬性數據

        int oc_mqtt_profile_gwpropertyreport(char *deviceid,oc_mqtt_profile_device_t *payload);

        用于批量設備上報屬性數據給平臺。網關設備可以用此接口同時上報多個子設備的屬性數據。

        參數描述deviceid設備idpayload要上傳的消息返回描述0上傳成功1上傳失敗4)屬性設置的響應結果

        int oc_mqtt_profile_propertysetresp(char *deviceid,oc_mqtt_profile_propertysetresp_t *payload);

        參數描述deviceid設備idpayload消息返回描述0上傳成功1上傳失敗5)屬性查詢響應結果

        int oc_mqtt_profile_propertygetresp(char *deviceid,oc_mqtt_profile_propertygetresp_t *payload);

        參數描述deviceid設備idpayload消息返回描述0上傳成功1上傳失敗6)將命令的執行結果返回給平臺

        int oc_mqtt_profile_cmdresp(char *deviceid,oc_mqtt_profile_cmdresp_t *payload);平臺下發命令后,需要設備及時將命令的執行結果返回給平臺,如果設備沒回響應,平臺會認為命令執行超時。

        參數描述deviceid設備idpayload要上傳的消息返回描述0上傳成功1上傳失敗3. 編寫業務邏輯1)連接平臺

        準備好上文我們獲取的連接信息(ClientId、Username、Password),一個可以上網的WIFI(賬戶和密碼),注意不可以用5G頻段。

        #define CLIENT_ID "60cdaf505f880902bcaa161c_senser_0_0_2021062002"
        #define USERNAME "60cdaf505f880902bcaa161c_senser"
        #define PASSWORD "e7f839333a8d3618a975e2626df1462f67202f3f4103080fe8d6f05df0fa7ce3"
        WifiConnect("TP-LINK_65A8","0987654321");
        device_info_init(CLIENT_ID,USERNAME,PASSWORD);
        oc_mqtt_init();
        oc_set_cmd_rsp_cb(oc_cmd_rsp_cb);
        2)推送數據

        當需要上傳數據時,需要先拼裝數據,然后通過oc_mqtt_profile_propertyreport上報數據。代碼示例如下:

        *
        * @brief   處理上報的數據。
        * @details   Process the reported data.
        * @param[in] report  需要上報的數據。The data to be reported.
        * @return    None
        **
        static void deal_report_msg(report_t *report)
        {
        * 定義服務ID句柄
           oc_mqtt_profile_service_t    service;
           * 定義溫度的上報數據句柄
           oc_mqtt_profile_kv_t         temperature;
           * 定義濕度的上報數據句柄
           oc_mqtt_profile_kv_t         humidity;
           * 定義亮度的上報數據句柄
           oc_mqtt_profile_kv_t         luminance;
           * 定義電燈的上報數據句柄
           oc_mqtt_profile_kv_t         led;
           * 定義電機的上報數據句柄
           oc_mqtt_profile_kv_t         motor;
        * 初始化要上報的服務ID數據
           service.event_time = NULL;
           service.service_id = "Agriculture";
           service.service_property = &temperature;
           service.nxt = NULL;

        * 初始化要上報的溫度數據
           temperature.key = "Temperature";
           temperature.value = &report->temp;
           temperature.type = EN_OC_MQTT_PROFILE_VALUE_INT;
           temperature.nxt = &humidity;
           
        * 初始化要上報的濕度數據
           humidity.key = "Humidity";
           humidity.value = &report->hum;
           humidity.type = EN_OC_MQTT_PROFILE_VALUE_INT;
           humidity.nxt = &luminance;
           
        * 初始化要上報的亮度數據
           luminance.key = "Luminance";
           luminance.value = &report->lum;
           luminance.type = EN_OC_MQTT_PROFILE_VALUE_INT;
           luminance.nxt = &led;
           
        * 初始化要上報的電燈數據
           led.key = "LightStatus";
           led.value = g_app_cb.led?"ON":"OFF";
           led.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
           led.nxt = &motor;
           
        * 初始化要上報的電機數據
           motor.key = "MotorStatus";
           motor.value = g_app_cb.motor?"ON":"OFF";
           motor.type = EN_OC_MQTT_PROFILE_VALUE_STRING;
           motor.nxt = NULL;

        * 將屬性數據上報給平臺
           oc_mqtt_profile_propertyreport(USERNAME,&service);
           return;
        }
        3)命令接收

        華為IoT平臺支持下發命令,命令是用戶自定義的。接收到命令后會將命令數據發送到隊列中,task_main_entry函數中讀取隊列數據并調用deal_cmd_msg函數進行處理,代碼示例如下:

        *
        * @brief   將命令數據發送到隊列。
        * @details   Send command data to the queue.
        * @param[in] recv_data  接收的數據
        * @param[in] recv_size  接收數據的大小
        * @param[in] resp_data  接收的上報數據
        * @param[in] resp_size  接收的上報數據的大小
        * @return    None
        **
        void oc_cmd_rsp_cb(uint8_t *recv_data, size_t recv_size, uint8_t **resp_data, size_t *resp_size)
        {
        app_msg_t *app_msg;
        int ret = 0;
        app_msg = malloc(sizeof(app_msg_t));
        app_msg->msg_type = en_msg_cmd;
        app_msg->msg.cmd.payload = (char *)recv_data;
           printf("recv data is %.*s", recv_size, recv_data);
           
           * 送入隊列
           ret = osMessageQueuePut(mid_MsgQueue,&app_msg,0U, 0U);
           
           if(ret != 0){
               free(recv_data);
           }
           *resp_data = NULL;
           *resp_size = 0;
        }
        *
        * @brief   線程入口,讀取隊列數據并處理。
        * @details   Thread entry, read queue data and process.
        * @param[in] None
        * @return    None
        **
        static int task_main_entry( void )
        {
           app_msg_t *app_msg;

        * 連接WIFI
        WifiConnect("TP-LINK_65A8","0987654321");
        * 注冊設備的連接信息
        device_info_init(CLIENT_ID,USERNAME,PASSWORD);
        * 初始化MQTT
        oc_mqtt_init();
        oc_set_cmd_rsp_cb(oc_cmd_rsp_cb);
           while(1){
               app_msg = NULL;
               (void)osMessageQueueGet(mid_MsgQueue,(void **)&app_msg,NULL, 0U);
               if(NULL != app_msg){
                   switch(app_msg->msg_type){
                       case en_msg_cmd:
                           deal_cmd_msg(&app_msg->msg.cmd);
                           break;
                       case en_msg_report:
                           deal_report_msg(&app_msg->msg.report);
                           break;
                       default:
                           break;
                   }
                   free(app_msg);
               }
           }
           return 0;
        }
        *
        * @brief   解析命令,并給出處理的結果。
        * @details   Thread entry, read queue data and process.
        * @param[in] cmd 命令。
        * @return    None
        **
        static void deal_cmd_msg(cmd_t *cmd)
        {
           cJSON *obj_root;
           cJSON *obj_cmdname;
           cJSON *obj_paras;
           cJSON *obj_para;
           int cmdret = 1;
           oc_mqtt_profile_cmdresp_t  cmdresp;
           obj_root = cJSON_Parse(cmd->payload);
           if(NULL == obj_root){
               goto EXIT_JSONPARSE;
           }
           obj_cmdname = cJSON_GetObjectItem(obj_root,"command_name");
           if(NULL == obj_cmdname){
               goto EXIT_CMDOBJ;
           }
           if(0 == strcmp(cJSON_GetStringValue(obj_cmdname),"Agriculture_Control_light")){
               obj_paras = cJSON_GetObjectItem(obj_root,"paras");
               if(NULL == obj_paras){
                   goto EXIT_OBJPARAS;
               }
               obj_para = cJSON_GetObjectItem(obj_paras,"light");
               if(NULL == obj_para){
                   goto EXIT_OBJPARA;
               }
               ///< operate the LED here
               if(0 == strcmp(cJSON_GetStringValue(obj_para),"ON")){
                   g_app_cb.led = 1;
                   Light_StatusSet(ON);
                   printf("Light On!");
               }
               else{
                   g_app_cb.led = 0;
                   Light_StatusSet(OFF);
                   printf("Light Off!");
               }
               cmdret = 0;
           }
           else if(0 == strcmp(cJSON_GetStringValue(obj_cmdname),"Agriculture_Control_Motor")){
               obj_paras = cJSON_GetObjectItem(obj_root,"paras");
               if(NULL == obj_paras){
                   goto EXIT_OBJPARAS;
               }
               obj_para = cJSON_GetObjectItem(obj_paras,"motor");
               if(NULL == obj_para){
                   goto EXIT_OBJPARA;
               }
               ///< operate the Motor here
               if(0 == strcmp(cJSON_GetStringValue(obj_para),"ON")){
                   g_app_cb.motor = 1;
                   Motor_StatusSet(ON);
                   printf("Motor On!");
               }
               else{
                   g_app_cb.motor = 0;
                   Motor_StatusSet(OFF);
                   printf("Motor Off!");
               }
               cmdret = 0;
           }
        EXIT_OBJPARA:
        EXIT_OBJPARAS:
        EXIT_CMDOBJ:
           cJSON_Delete(obj_root);
        EXIT_JSONPARSE:
           ///< do the response
           cmdresp.paras = NULL;
           cmdresp.request_id = cmd->request_id;
           cmdresp.ret_code = cmdret;
           cmdresp.ret_name = NULL;
           (void)oc_mqtt_profile_cmdresp(NULL,&cmdresp);
           return;
        }
        4. 編譯調試

        修改 applicationssampleBearPiBearPi-HM_Nano路徑下 BUILD.gn 文件,指定 oc_mqtt 參與編譯。

        #"D1_iot_wifi_sta:wifi_sta",
        #"D2_iot_wifi_sta_connect:wifi_sta_connect",      
        #"D3_iot_udp_client:udp_client",
        #"D4_iot_tcp_server:tcp_server",
        #"D5_iot_mqtt:iot_mqtt",        
        "D6_iot_cloud_oc:oc_mqtt",
        #"D7_iot_cloud_onenet:onenet_mqtt",

        示例代碼編譯燒錄代碼后,按下開發板的RESET按鍵,通過串口助手查看日志,會打印溫濕度及光照強度信息。

        sdk ver:Hi3861V100R001C00SPC025 2020-09-03 18:10:00
        FileSystem mount ok.
        wifi init success!
        00 00:00:00 0 68 D 0/HIVIEW: hilog init success.
        00 00:00:00 0 68 D 0/HIVIEW: log limit init success.
        00 00:00:00 0 68 I 1/SAMGR: Bootstrap core services(count:3).
        00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b8040 TaskPool:0xfa9a4
        00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b8064 TaskPool:0xfb014
        00 00:00:00 0 68 I 1/SAMGR: Init service:0x4b81c8 TaskPool:0xfb1d4
        00 00:00:00 0 100 I 1/SAMGR: Init service 0x4b8064

        回到華為云平臺,平臺上的設備顯示為在線狀態

        點擊設備右側的“查看”,進入設備詳情頁面,可看到上報的數據

        在華為云平臺設備詳情頁,單擊“命令”,選擇同步命令下發,選中創建的命令屬性,單擊“確定”,即可發送下發命令控制設備。

        看一下現象:串口打印云端接收的數據,并執行點燈的指令。

        5. 調試華為云API

        點擊「API檢索和調試」,進入API調測界面。

        目前開放有Java、python、node.js、php等,可以根據個人的需求,構建前端。這里我們先調試API,選擇一個設備命令,按照圖示操作。注意Body里面的參數,與我們上文產品的屬性是一樣的,其中paras的參數,填寫要符合圖片給出的規范,也就是JSON的格式。

        最后點擊調式,給出調試結果,我們的開發板上,燈也被點亮!

        四、總結

        云端的操作,要注意和終端軟件編寫的信息相同,一個是MQTT的連接信息不能出錯,還有就是注意名稱之間的大小寫要相同;終端MCU軟件的編寫,注意分層設計,先寫好各自的功能模塊,最后再實現相關的業務邏輯;注意調測,利用好串口和云端MQTT信息跟蹤服務;整體走下來,工作量還是蠻大的,需要注意的地方有很多,所以要特別細心。源代碼后臺回復鴻蒙獲取,工程文件可以參考上個文章獲取。

        <上一頁  1  2  
        聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權或其他問題,請聯系舉報。

        發表評論

        0條評論,0人參與

        請輸入評論內容...

        請輸入評論/評論長度6~500個字

        您提交的評論過于頻繁,請輸入驗證碼繼續

        暫無評論

        暫無評論

          掃碼關注公眾號
          OFweek人工智能網
          獲取更多精彩內容
          文章糾錯
          x
          *文字標題:
          *糾錯內容:
          聯系郵箱:
          *驗 證 碼:

          粵公網安備 44030502002758號

          主站蜘蛛池模板: 人人干人人爽| 久久久久久AV| 日韩AV高清无码| 天天插天天透| 97福利在线| 一本一道久久综合狠狠躁牛牛影视| 96福利视频| 中文字幕日产av| 国产成人一区二区三区A片免费| 五月丁香伊人| 中文字幕精品久久久久人妻红杏1| 亚洲熟妇无码成人A片| 亚洲最大的成人网| A片AV| 国产传媒_色哟哟| 久久999| 亚洲最大的成人网站| 留坝县| AV免费网站| 丰满少妇被猛烈进入| 91资源在线| 91精品导航| 国产AV一区二区三区| 激情婷婷五月天| 国产精品制度丝袜电影| 沽源县| 亚洲v欧美| 浪荡干片网在线观看| 枣强县| 中日韩在线| 欧韩一区| 国产在线你懂| 昌平区| 91网在线| 51超碰| 人妻综合网| 报价| 久久巨| 美女秘密91| 91在线小视频| 亚洲综合乱|