天天看點

遠端台燈功能

簡介

碰一碰特性是HarmonyOS具備的多終端業務協同技術。通過碰一碰的互動方式,可以将手機和全場景裝置連接配接起來。再通過手機端的原子化服務能力,快速完成配網、遠端控制。解決了應用與裝置之間接續慢、配網複雜、傳輸難的問題,為使用者帶來無縫切換的流暢體驗。

本篇Codelab将指導大家如何開發一個模拟的“遠端台燈”案例。在本案例中,通過手機碰一碰NFC标簽,可以從HAG擷取到關聯意圖資訊。通過擷取到的關聯意圖資訊,可以拉起對應的原子化服務。該原子化服務通過調用hilink接口,并結合裝置側代碼實作,可以完成開發闆與手機間的配網并建立通信通道。完成此步驟後,即可通過手機控制Hi3861開發版中LED燈的開關了。

遠端台燈功能

通過該案例,大家将會學會:

通過碰一碰能力,拉起手機端原子化服務。

快速完成手機與裝置的配網。

通過手機對裝置進行控制。

說明: 本指導僅用于個人開發者體驗HarmonyOS碰一碰特性,不能作為商用方案進行碰一碰特性的開發和上架。

實物簡介

Hi3861開發闆

華為手機,系統版本為HarmonyOS 2.0.0.168及以上,手機具體型号為Mate 40 Pro。将手機上智慧生活基礎服務更新至12.0.0.306及以上版本。具體操作步驟如下:

檢視“智慧生活基礎服務”版本,打開手機“設定>應用服務>應用管理”,搜尋“智慧生活基礎服務”。

更新“智慧生活基礎服務”,打開手機“智慧生活”App,點選“我的 > 設定 > 檢查應用更新”,更新“智慧生活基礎服務”。

Hi3861開發闆

本樣例基于Hi3861開發闆開發,請準備Hi3861開發闆(HiSpark Wi-Fi IoT智能家居套件)。包含開發闆主機闆、底闆和OLED闆。

遠端台燈功能

HarmonyOS原子化服務開發

建立工程

裝置配網原子化服務(entry)

裝置控制原子化服務(control)

本案例将要實作“碰一碰-拉起原子化服務-裝置配網-裝置控制”的完整流程,整個流程都要基于手機端的原子化服務實作。開發原子化服務使用的工具為DevEco Studio 3.0 Beta2,關于工具配置請檢視官方指導文檔搭建開發環境流程。

打開建立工程向導界面,選擇“Empty Ability”模闆建立原子化服務,用于裝置配網。

遠端台燈功能

在工程配置中,Project type選擇“Atomic Service”,并打開“Show in Service Center”選項,點選Finish按鈕即可完成建立裝置配網原子化服務。

遠端台燈功能

在已建立好的“entry”目錄上右擊,選擇“Empty Ability”模闆建立一個Module,用于裝置控制。

遠端台燈功能

在子產品配置界面,“Module type”中選擇的“Feature”,點選“Next”。

遠端台燈功能

配置Module的“Page ability name”,點選“Finish”完成建立。

遠端台燈功能

裝置配網原子化服務(entry)

配網過程需要依賴hilink的接口,是以首先需要在entry\build.gradle中加入對hilink的依賴。

dependencies {
    ...
    ohosTestImplementation 'com.huawei.ohos.testkit:runner:2.0.0.200'
}
           

手機碰一碰nfc标簽,将會拉起用于配網的原子化服務(entry子產品)。在服務的入口MainAbility中,完成了對nfc中的産品資訊的讀取,以及将“abilityContext”和從意圖中擷取的“nanSessionId”注冊到用于配網的NetConfigAbility中。

// 讀取産品資訊
Object productInfo = Objects.requireNonNull(intent.getParams()).getParam("productInfo");
if (productInfo != null) {
    productId = (String) productInfo;
}

// 從intent中讀取的nanSessionId用于配網,同時需要将abilityContext和sessionId注冊到NetConfigAbility中
String sessionId = intent.getStringParam("nanSessionId");
if ("null".equals(sessionId) || "".equals(sessionId)) {
    NetConfigAbility.register(this, null);
} else {
    NetConfigAbility.register(this, sessionId);
}
           

entry子產品的主界面在初始化時,會将産品資訊和“nanSessionId”在應用中儲存傳遞。

onInit() {
    this.deviceName = this.$t('strings.device-name');
    this.deviceImg = '/common/images/LED.png';
    getApp(this).Product.productName = this.productName;
    getApp(this).Product.productId = this.productId;
    getApp(this).ConfigParams.sessionId = this.sessionId;
}
           

點選主界面的“配網”按鈕,會預設進行配網操作。主要分為5個步驟,均依賴hilink接口實作,具體代碼可檢視netconfig.js。

通過NAN廣播服務搜尋裝置。

getApp(this).NetConfig.discoveryByNAN(scanInfo, (result) => {
    if (result.code == 0) {
       // 成功發現裝置
    } else {
       ...
    }
});
           

連接配接裝置。

getApp(this).NetConfig.connectDevice(connectInfo, (result) => {
    if (result.code === 0) {
        // 裝置連接配接成功
    } else {
        ...
    }
});
           

擷取wifi資訊。

getApp(this).NetConfig.getWifiList((result) => {
    if (result.code == 0 && result.data && result.data.length > 0) {
        // 擷取wifi資訊成功
    } else {
        ...
    }
});
           

對裝置進行網絡配置。

getApp(this).NetConfig.configDeviceNet('deviceInfo', 'accountInfo', netConfigInfo, (result) => {
    if (result.code == 0) {
        // 裝置網絡配置成功
    } else {
        ...
    }
});
           

配網成功,跳轉至裝置控制子產品。

goToControl() {
    let target = {
        bundleName: 'com.huawei.smartlamp.hmservice',
        abilityName: 'com.huawei.smartlamp.ControlMainAbility',
        deviceType: 1,// 從本地裝置中拉起原子化服務
        data: {
            session_id: getApp(this).ConfigParams.deviceInfo.sessionId,
            product_id: getApp(this).Product.productId,
            product_name: getApp(this).Product.productName
        }
    }
    FeatureAbility.startAbility(target);
    app.terminate()
}
           

裝置控制原子化服務(control)

通過control子產品控制開發版led燈的開關,依賴hilink的接口發送指令,是以需要在control\build.gradle添加對應依賴。

dependencies {    ...    implementation(group: 'com.huawei.hilink', name: 'ailifeability', version: '1.0.0.1', ext: 'har')}
           

當成功完成裝置配網後,手機會自動拉起裝置控制原子化服務(control)。在控制服務界面點選開關按鈕時,會利用FeatureAbility子產品(JS端SDK接口)的能力,調用PA向開發闆發送指令,NetConfigApi由引入的hilink子產品提供。

private void sendMessage(String message, HashMap<String, Object> tmpMap) {    CommonInfo commonInfo = new CommonInfo();    commonInfo.setSessionId(sessionId);    HiLog.error(LABEL_LOG, "sessionId " + sessionId);    NetConfigApi.getInstance().sendMessage(commonInfo, message, (code, controlMessage, str) -> {        ...    });}
           

Hi3861開發環境準備

Hi3861支援多種開發環境的搭建:

搭建Windows開發環境

搭建Windows+Ubuntu混合開發環境

搭建Ubuntu開發環境

開發者可以根據自身的情況搭建合适的開發環境。

源碼下載下傳與編譯前準備

代碼下載下傳

編譯前準備

本案例将使用Ubuntu開發環境,基于OpenHarmony-3.0-LTS源碼進行開發。

代碼下載下傳

通過repo工具下載下傳OpenHarmony-3.0-LTS的源碼:

repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony-3.0-LTS --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
           

編譯前準備

編譯前,需要調整OpenHarmony源碼,并添加裝置側代碼,以實作裝置配網與裝置控制的功能。

修改device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk檔案,開啟對I2C的支援。

CONFIG_I2C_SUPPORT=y
           

修改device/hisilicon/hispark_pegasus/hi3861_adapter/hals/communication/wifi_lite/wifiservice/source/wifi_hotspot.c檔案,在EnableHotspot函數中注釋如下代碼。

//if (SetHotspotIpConfig() != WIFI_SUCCESS) {
//    return ERROR_WIFI_UNKNOWN;
//}
           

修改device/hisilicon/hispark_pegasus/hi3861_adapter/hals/communication/wifi_lite/wifiservice/source/wifi_device.c檔案,在DispatchConnectEvent函數中注釋StaSetWifiNetConfig相關代碼。

//StaSetWifiNetConfig(HI_WIFI_EVT_CONNECTED);
//StaSetWifiNetConfig(HI_WIFI_EVT_DISCONNECTED);
           

修改base/security/huks/interfaces/innerkits/huks_lite/BUILD.gn檔案,注釋如下代碼。

#sources += [ "hks_tmp_client.c" ]

在OpenHarmony源碼的third_party目錄下,添加IoTDA平台SDK。

遠端台燈功能

在vendor目錄下,添加裝置側代碼team_x。目錄結構如下圖所示。

遠端台燈功能

“common”中主要包含本樣例依賴的頭檔案和類庫檔案。“smart_lamp”中則包含了本樣例中裝置側的核心代碼。“smart_lamp”目錄結構如下圖所示。

遠端台燈功能

樣例入口檔案iot_main.c位于demo_smartlamp/src目錄下,當啟動開發闆時,會啟動入口線程任務。在該任務中,開發闆會完成I2C初始化、OLED初始化,進入配網狀态并注冊網絡監聽事件。

static void *LampTask(const char *arg)
{
    (void)arg;
    WINDBG("LampTask Enter! \n");
    LampInit();
    (void)memset_s(&g_lamp, sizeof(g_lamp), 0x00, sizeof(g_lamp));

    NetCfgRegister(LampNetEventHandler);  // 進入配網狀态并注冊網絡監聽事件
    LampShowInfo();       // 顯示LED初始狀态
}
           

配網成功,并成功注冊網絡監聽事件後,手機端每次發送指令,都會觸發監聽事件,進而對開發闆裝置上LED燈進行開關控制。

static int LampNetEventHandler(NET_EVENT_TYPE event, void *data)
{
    switch (event) {
        case NET_EVENT_RECV_DATA: // 接收到網絡資訊(FA發送的消息)
            LampProcessAppMessage((const char *)data, strlen(data)); // 處理對應的資訊
            break;
        default:
            break;
    }
    return 0;
}
           

編譯和燒錄

編譯

進入源碼根目錄,首次編譯,輸入編譯指令“hb set”。随後在Input code path指令行中鍵入“.”,指定OpenHarmony工程編譯根目錄後回車。

遠端台燈功能

選擇智能台燈“smart_lamp”并回車,輸入“hb build”指令進行編譯,螢幕出現:BUILD SUCCESS字樣,說明編譯成功。

遠端台燈功能

燒錄

将編譯生成檔案下載下傳至本地Windows環境。

遠端台燈功能

将Hi3861通過TypeC資料線與電腦連接配接。

使用Hiburn工具進行燒錄:

點選“Refresh”按鈕,更新com端口資訊。在“COM”處選擇Hi3861開發闆對應的COM口。選擇編譯生成的二進制檔案,勾選“Auto burn”,随後點選“connect”按鈕。此時點選Hi3861開發闆上的“RST”鍵,進行燒錄。

遠端台燈功能

檢視燒錄進度,等待進度跑完,則燒錄完成。可點選“Disconnect”斷開連接配接。

遠端台燈功能

源碼下載下傳與編譯前準備

代碼下載下傳

編譯前準備

本案例将使用Ubuntu開發環境,基于OpenHarmony-3.0-LTS源碼進行開發。

代碼下載下傳

通過repo工具下載下傳OpenHarmony-3.0-LTS的源碼:

repo init -u https://gitee.com/openharmony/manifest.git -b OpenHarmony-3.0-LTS --no-repo-verify
repo sync -c
repo forall -c 'git lfs pull'
           

編譯前準備

編譯前,需要調整OpenHarmony源碼,并添加裝置側代碼,以實作裝置配網與裝置控制的功能。

修改device/hisilicon/hispark_pegasus/sdk_liteos/build/config/usr_config.mk檔案,開啟對I2C的支援。

CONFIG_I2C_SUPPORT=y
           

修改device/hisilicon/hispark_pegasus/hi3861_adapter/hals/communication/wifi_lite/wifiservice/source/wifi_hotspot.c檔案,在EnableHotspot函數中注釋如下代碼。

//if (SetHotspotIpConfig() != WIFI_SUCCESS) {
//    return ERROR_WIFI_UNKNOWN;
//}
           

修改device/hisilicon/hispark_pegasus/hi3861_adapter/hals/communication/wifi_lite/wifiservice/source/wifi_device.c檔案,在DispatchConnectEvent函數中注釋StaSetWifiNetConfig相關代碼。

//StaSetWifiNetConfig(HI_WIFI_EVT_CONNECTED);
//StaSetWifiNetConfig(HI_WIFI_EVT_DISCONNECTED);
           

修改device/hisilicon/hispark_pegasus/sdk_liteos/BUILD.gn檔案,在deps中添加如下代碼。

deps = [
    ...
    "//build/lite:product",
  ]
           

修改base/security/huks/interfaces/innerkits/huks_lite/BUILD.gn檔案,注釋如下代碼。

#sources += [ "hks_tmp_client.c" ]
           

在OpenHarmony源碼的third_party目錄下,添加IoTDA平台SDK。

遠端台燈功能

在vendor目錄下,添加裝置側代碼team_x。目錄結構如下圖所示。

遠端台燈功能

“common”中主要包含本樣例依賴的頭檔案和類庫檔案。“smart_lamp”中則包含了本樣例中裝置側的核心代碼。“smart_lamp”目錄結構如下圖所示。

遠端台燈功能
static void *LampTask(const char *arg)
{
    (void)arg;
    WINDBG("LampTask Enter! \n");
    LampInit();
    (void)memset_s(&g_lamp, sizeof(g_lamp), 0x00, sizeof(g_lamp));

    NetCfgRegister(LampNetEventHandler);  // 進入配網狀态并注冊網絡監聽事件
    LampShowInfo();       // 顯示LED初始狀态
}
           

配網成功,并成功注冊網絡監聽事件後,手機端每次發送指令,都會觸發監聽事件,進而對開發闆裝置上LED燈進行開關控制。

static int LampNetEventHandler(NET_EVENT_TYPE event, void *data)
{
    switch (event) {
        case NET_EVENT_RECV_DATA: // 接收到網絡資訊(FA發送的消息)
            LampProcessAppMessage((const char *)data, strlen(data)); // 處理對應的資訊
            break;
        default:
            break;
    }
    return 0;
}
           

編譯

進入源碼根目錄,首次編譯,輸入編譯指令“hb set”。随後在Input code path指令行中鍵入“.”,指定OpenHarmony工程編譯根目錄後回車。

遠端台燈功能

選擇智能台燈“smart_lamp”并回車,輸入“hb build”指令進行編譯,螢幕出現:BUILD SUCCESS字樣,說明編譯成功。

遠端台燈功能

燒錄

将編譯生成檔案下載下傳至本地Windows環境。

遠端台燈功能

将Hi3861通過TypeC資料線與電腦連接配接。

使用Hiburn工具進行燒錄:

點選“Refresh”按鈕,更新com端口資訊。在“COM”處選擇Hi3861開發闆對應的COM口。選擇編譯生成的二進制檔案,勾選“Auto burn”,随後點選“connect”按鈕。此時點選Hi3861開發闆上的“RST”鍵,進行燒錄。

遠端台燈功能

檢視燒錄進度,等待進度跑完,則燒錄完成。可點選“Disconnect”斷開連接配接。

遠端台燈功能

裝置配網

使用應用調測助手App,在NFC标簽中寫入對應的标簽資訊,具體請參考寫入NFC标簽資訊。

通過在HAG上配置原子化關聯意圖,在手機碰一碰NFC标簽後,即可擷取需要拉取的原子化服務資訊,具體請參考配置服務關聯意圖。

在手機上安裝開發好的原子化服務。注意該項目包含兩個子產品,簽名需要使用項目級簽名。

遠端台燈功能

打開Run > Edit Configurations, 勾選entry子產品下的“Deploy Multi Hap Packages”選項,表示在運作entry子產品(裝置配網原子化服務)時,同時會在手機中安裝control子產品(裝置控制原子化服務)。

遠端台燈功能

打開手機NFC功能,确認手機已經接入WLAN無線網絡。使用手機背部接觸NFC标簽,手機會彈出以下頁面。

遠端台燈功能

點選Hi3861開發闆的RST複位按鍵,點選手機上的配網按鈕,即開始手機與開發闆的配網過程。配網成功後,手機應用将自動跳轉至控制界面,如下圖。

遠端台燈功能

操作體驗

配網成功後,即可通過手機對Hi3861開發闆LED燈進行開關操作。

遠端台燈功能

繼續閱讀