OpenHarmony繼續(xù)上云之騰訊云平臺(tái)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
一.前面的話
說實(shí)話,騰訊云物聯(lián)網(wǎng)平臺(tái)一直是我比較喜歡的物聯(lián)網(wǎng)云太平,除了有騰訊大廠作為品質(zhì)背書之外,提供的sdk也是相當(dāng)好用,更有騰訊連連小程序可以幫助做界面,調(diào)試功能,后端的API有java,c++,Golang,js,python等等語(yǔ)言版本,非常方便,簡(jiǎn)直是上云首選.
二.首先下載sdk
我們首先來找官方sdk,茫茫文檔中給我看到了那熟悉的身影:

文檔地址在這,拿走不謝:
https://cloud.tencent.com/document/product/1081/48356
把sdk下載之后,熟練的放進(jìn)thirdparty文件夾,

不得不提一下,2.x版本的OpenHarmony比1.x版本的代碼結(jié)構(gòu)清晰多了.
1.實(shí)現(xiàn)幾個(gè)重要接口
這個(gè)時(shí)候依然要看文檔,因?yàn)橛行┖瘮?shù)需要自己實(shí)現(xiàn),具體是哪些呢,在這里:
https://cloud.tencent.com/document/product/1081/48389
這篇文檔寫了,我們要實(shí)現(xiàn)里面的這些接口,此處列舉一二:


仔細(xì)一看,霍,好家伙還不少呢,但是不怕,都是打工人,誰怕誰啊,二話不說我就寫,結(jié)果就給我給寫出來了:

寫出來這些后就可以準(zhǔn)備編譯了嗎?
nonono,我們還沒做BUILD.gn文件呢,話不多說,直接教你寫。
- # Copyright (c) 2020 Huawei Device Co., Ltd.
 - # Licensed under the Apache License, Version 2.0 (the "License");
 - # you may not use this file except in compliance with the License.
 - # You may obtain a copy of the License at
 - #
 - # http://www.apache.org/licenses/LICENSE-2.0
 - #
 - # Unless required by applicable law or agreed to in writing, software
 - # distributed under the License is distributed on an "AS IS" BASIS,
 - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - # See the License for the specific language governing permissions and
 - # limitations under the License.
 - import("//build/lite/config/component/lite_component.gni")
 - import("//build/lite/ndk/ndk.gni")
 - config("qcloud_sdk_config") {
 - include_dirs = [
 - "sdk_src/internal_inc",
 - "sdk_src/library",
 - "include",
 - "include/exports",
 - "//kernel/liteos_m/kernel/include",
 - # "//third_party/cmsis",
 - "//third_party/mbedtls/include",
 - "//third_party/mbedtls/include/mbedtls",
 - ]
 - }
 - cflags = [ "-Wno-unused-variable" ]
 - cflags += [ "-Wno-unused-but-set-variable" ]
 - cflags += [ "-Wno-unused-parameter" ]
 - cflags += [ "-Wno-sign-compare" ]
 - cflags += [ "-Wno-unused-function" ]
 - cflags += [ "-Wno-return-type" ]
 - qcloud_sdk_sources = [
 - "sdk_src/network/socket/network_socket.c",
 - "sdk_src/network/tls/network_tls.c",
 - "sdk_src/network/network_interface.c",
 - "sdk_src/utils/utils_list.c",
 - "sdk_src/utils/utils_base64.c",
 - "sdk_src/utils/qcloud_iot_ca.c",
 - "sdk_src/utils/utils_aes.c",
 - "sdk_src/utils/utils_getopt.c",
 - "sdk_src/utils/utils_hmac.c",
 - "sdk_src/utils/utils_md5.c",
 - "sdk_src/utils/utils_sha1.c",
 - "sdk_src/utils/json_parser.c",
 - "sdk_src/utils/json_token.c",
 - "sdk_src/utils/string_utils.c",
 - "sdk_src/utils/utils_ringbuff.c",
 - "sdk_src/utils/qcloud_iot_log.c",
 - "sdk_src/utils/qcloud_iot_device.c",
 - "sdk_src/utils/utils_timer.c",
 - "sdk_src/protocol/mqtt/mqtt_client_common.c",
 - "sdk_src/protocol/mqtt/mqtt_client_connect.c",
 - "sdk_src/protocol/mqtt/mqtt_client_net.c",
 - "sdk_src/protocol/mqtt/mqtt_client_publish.c",
 - "sdk_src/protocol/mqtt/mqtt_client_subscribe.c",
 - "sdk_src/protocol/mqtt/mqtt_client_unsubscribe.c",
 - "sdk_src/protocol/mqtt/mqtt_client_yield.c",
 - "sdk_src/protocol/mqtt/mqtt_client.c",
 - "sdk_src/services/data_template/data_template_action.c",
 - "sdk_src/services/data_template/data_template_client.c",
 - "sdk_src/services/data_template/data_template_client_common.c",
 - "sdk_src/services/data_template/data_template_client_json.c",
 - "sdk_src/services/data_template/data_template_client_manager.c",
 - "sdk_src/services/data_template/data_template_event.c",
 - "platform/os/liteos_m/HAL_Device_liteos_m.c",
 - "platform/os/liteos_m/HAL_OS_liteos_m.c",
 - "platform/os/liteos_m/HAL_TCP_liteos_m.c",
 - "platform/os/liteos_m/HAL_Timer_liteos_m.c",
 - # "./os/liteos_m/HAL_TLS_mbedtls_liteos_m.c",
 - # "./tls/mbedtls/HAL_DTLS_mbedtls.c",
 - "platform/tls/mbedtls/HAL_TLS_mbedtls.c",
 - ]
 - lite_library("qcloud_sdk_static") {
 - target_type = "static_library"
 - sources = qcloud_sdk_sources
 - public_configs = [ ":qcloud_sdk_config" ]
 - }
 - lite_library("qcloud_sdk_shared") {
 - target_type = "shared_library"
 - sources = qcloud_sdk_sources
 - public_configs = [ ":qcloud_sdk_config" ]
 - }
 - ndk_lib("qcloud_ndk") {
 - if (board_name != "hi3861v100") {
 - lib_extension = ".so"
 - deps = [
 - ":qcloud_sdk_shared"
 - ]
 - } else {
 - deps = [
 - ":qcloud_sdk_static"
 - ]
 - }
 - head_files = [
 - "//third_party/iot_link/network/mqtt/paho_mqtt/paho"
 - ]
 - }
 
整完之后就可以嘗試一下有沒有錯(cuò)誤了.
2.在main里面寫邏輯,處理事情
我們把官方sdk里面的點(diǎn)燈demo拿過來,直接新建一個(gè)demo文件夾,把文件放進(jìn)去:

自己寫好BUILD.gn,跟之前華為云對(duì)接一個(gè)套路,大家這么聰明,不用我多說了:
- # Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
 - # Licensed under the Apache License, Version 2.0 (the "License");
 - # you may not use this file except in compliance with the License.
 - # You may obtain a copy of the License at
 - #
 - # http://www.apache.org/licenses/LICENSE-2.0
 - #
 - # Unless required by applicable law or agreed to in writing, software
 - # distributed under the License is distributed on an "AS IS" BASIS,
 - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 - # See the License for the specific language governing permissions and
 - # limitations under the License.
 - static_library("qcloud_demo") {
 - sources = [
 - # "iot_thread.c",
 - "light.c",
 - "light_data_template_sample.c"
 - ]
 - cflags = [ "-Wno-unused-variable" ]
 - cflags += [ "-Wno-unused-but-set-variable" ]
 - include_dirs = [
 - ".",
 - "//foundation/communication/softbus_lite/os_adapter/include",
 - "//utils/native/lite/include",
 - "//kernel/liteos_m/components/cmsis/2.0",
 - "//base/iot_hardware/peripheral/interfaces/kits",
 - "//third_party"
 - ]
 - deps = [
 - "//third_party/qcloud-iot-explorer-sdk-embedded-c-3.2.0:qcloud_sdk_static",
 - # "//third_party/qcloud-iot-explorer-sdk-embedded-c-3.2.0/external_libs/mbedtls:mbedtls_static",
 - ]
 - }
 
然后在sample里面的sdk把這個(gè)文件夾開啟編譯:

這樣就完成了代碼的編寫了,很快樂有木有。
三.在云平臺(tái)上創(chuàng)建設(shè)備
其實(shí)創(chuàng)建設(shè)備的過程官方文檔也的確挺詳細(xì)的,幾乎不用再另外加工,這里給出官方的智能燈接入指南:
https://cloud.tencent.com/document/product/1081/41155
官方定義了許多的物模型,其實(shí)我們的產(chǎn)品可能是官方物模型沒有定義的,此時(shí)我們就需要自己定義產(chǎn)品的屬性,事件和動(dòng)作等,這塊自己仔細(xì)閱讀官方文檔就能搞懂
https://cloud.tencent.com/document/product/1081/34916
搞定了物模型,創(chuàng)建一個(gè)設(shè)備,記錄下設(shè)備的產(chǎn)品id,設(shè)備id和連接秘鑰
這點(diǎn)跟華為云平臺(tái)不太一樣,騰訊云的產(chǎn)品秘鑰是平臺(tái)生成的,而華為云平臺(tái)是你自己定義好設(shè)備的秘鑰,在創(chuàng)建設(shè)備的時(shí)候傳上去
四.編譯,運(yùn)行
編譯的過程倒是很順利,這里就不過多廢話了.
不過在運(yùn)行的時(shí)候出現(xiàn)一個(gè)情況,就是mutex不夠用了
自己折騰了一晚上也沒找不解決辦法,后面經(jīng)過請(qǐng)教猴哥才搞明白:
阿不對(duì),下面這個(gè)候哥才對(duì),大家可以去他主頁(yè)關(guān)注一下:
https://harmonyos.51cto.com/user/posts/13519852
候哥真大神也,短短一兩句話就幫我搞定了,在此特別感謝侯哥的幫助:

然后我就把我的mutex相關(guān)代碼改成posix接口,這是修改之前的:
- void *HAL_MutexCreate(void)
 - {
 - osMutexAttr_t attr;
 - osMutexId_t mutex;
 - char mutexName[RT_NAME_MAX];
 - static uint32_t mutex_v;
 - attr.name = mutexName;
 - attr.cb_mem = &mutex_v;
 - attr.cb_size = 4;
 - mutex = osMutexNew(&attr);
 - if (NULL == mutex) {
 - HAL_Printf("create mutex failed");
 - }
 - return mutex;
 - }
 - void HAL_MutexDestroy(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = osMutexDelete((osMutexId_t)mutex);
 - if (0 != err_num) {
 - HAL_Printf("destroy mutex failed");
 - }
 - }
 - void HAL_MutexLock(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = osMutexAcquire((osMutexId_t)mutex, osWaitForever);
 - if (0 != err_num) {
 - HAL_Printf("lock mutex failed");
 - }
 - }
 - void HAL_MutexUnlock(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = osMutexRelease((osMutexId_t)mutex);
 - if (0 != err_num) {
 - HAL_Printf("unlock mutex failed");
 - }
 - }
 - int HAL_MutexTryLock(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = osMutexAcquire((osMutexId_t)mutex, osNoWait);
 - if (0 != err_num) {
 - HAL_Printf("trylock mutex failed");
 - }
 - return err_num;
 - }
 
改完之后是這樣:
- void *HAL_MutexCreate(void)
 - {
 - // osMutexAttr_t attr;
 - // osMutexId_t mutex;
 - char mutexName[RT_NAME_MAX];
 - static uint32_t mutex_v;
 - pthread_mutex_t * mutex = HAL_Malloc(sizeof(pthread_mutex_t));
 - pthread_mutexattr_t attr;
 - int ret = pthread_mutex_init(mutex, &attr); // osMutexNew(&attr);
 - // if (NULL == mutex) {
 - if (ret != 0) {
 - HAL_Printf("create mutex failed\n");
 - }
 - return mutex;
 - }
 - void HAL_MutexDestroy(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = pthread_mutex_destroy(mutex);
 - if (0 != err_num) {
 - HAL_Printf("destroy mutex failed");
 - }
 - }
 - void HAL_MutexLock(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = pthread_mutex_lock(mutex);
 - if (0 != err_num) {
 - HAL_Printf("lock mutex failed");
 - }
 - }
 - void HAL_MutexUnlock(_IN_ void *mutex)
 - {
 - int err_num;
 - err_num = pthread_mutex_unlock(mutex);
 - if (0 != err_num) {
 - HAL_Printf("unlock mutex failed");
 - }
 - }
 - int HAL_MutexTryLock(_IN_ void *mutex)
 - {
 - int err_num;
 - struct timespec absTimeout={0,0};
 - err_num = pthread_mutex_timedlock(mutex, &absTimeout);
 - if (0 != err_num) {
 - HAL_Printf("trylock mutex failed");
 - }
 - return err_num;
 - }
 
使用的時(shí)候記得加上頭文件: #include
處理完這個(gè)異常情況,接下來就很順利的登錄騰訊云平臺(tái)收發(fā)數(shù)據(jù)了
五.云平臺(tái)控制展示
直接查看動(dòng)圖,控制還是很及時(shí)的:

六.總結(jié)
其實(shí)對(duì)接騰訊云還是蠻簡(jiǎn)單的,最新版的sdk在打印上也比以前好多了.OpenHarmony的2.x版本優(yōu)化了不少東西,記得去年這時(shí)候用1.x版本對(duì)接的時(shí)候還是很費(fèi)勁的,給OpenHarmony團(tuán)隊(duì)點(diǎn)贊,也給騰訊云團(tuán)隊(duì)點(diǎn)贊
大家趕緊玩起來吧
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
















 
 
 







 
 
 
 