生活物聯(lián)網(wǎng)平臺(tái)支持您在自有App中集成批量配網(wǎng)功能,可以實(shí)現(xiàn)一次性為多個(gè)相同型號(hào)的設(shè)備配網(wǎng),單次最多可批量配網(wǎng)20個(gè)設(shè)備。

前提條件

方案介紹

批量配網(wǎng)方案是基于設(shè)備熱點(diǎn)配網(wǎng)方案的基礎(chǔ)上開(kāi)發(fā)的方案,因此設(shè)備需要支持設(shè)備熱點(diǎn)配網(wǎng)和零配配網(wǎng)。批量配網(wǎng)方案的時(shí)序圖如下所示。

jt11
  1. 設(shè)備上電或操作設(shè)備按鍵,將所有待添加的設(shè)備進(jìn)入設(shè)備熱點(diǎn)配網(wǎng)模式。
  2. 通過(guò)App對(duì)其中一個(gè)設(shè)備進(jìn)行設(shè)備熱點(diǎn)配網(wǎng),并完成配網(wǎng)及綁定操作。調(diào)用的SDK請(qǐng)參見(jiàn)Android App SDKiOS App SDK
  3. 指定2中完成配網(wǎng)的設(shè)備為主設(shè)備,并通過(guò)主設(shè)備去發(fā)現(xiàn)其他待配網(wǎng)設(shè)備。

    主設(shè)備發(fā)送廣播消息,其他待配網(wǎng)設(shè)備接收到廣播消息后切換至零配模式。此時(shí),主設(shè)備可以發(fā)現(xiàn)進(jìn)入零配模式的待配網(wǎng)設(shè)備,并在App SDK回調(diào)中反饋搜索到的設(shè)備信息。

  4. 3中返回的其他待配網(wǎng)設(shè)備,通過(guò)零配配網(wǎng)方式完成配網(wǎng),并在App SDK回調(diào)中會(huì)反饋配網(wǎng)結(jié)果。

集成設(shè)備端

  1. 獲取生活物聯(lián)網(wǎng)平臺(tái)SDK V1.3.0及以上版本。請(qǐng)參見(jiàn)SDK概述與開(kāi)發(fā)環(huán)境設(shè)置
  2. 使能SDK中功能模塊。

    在應(yīng)用的mk文件中增加配置項(xiàng)GLOBAL_CFLAGS += -DAWSS_BATCH_DEVAP_ENABLE。如您基于living_platform開(kāi)發(fā),在living_platform.mk文件中已包含該配置項(xiàng),如下圖所示。

    jt40

    設(shè)備端SDK以及芯片需要支持的基本能力如下。

    • SDK的基本能力要求
      • 支持設(shè)備熱點(diǎn)配網(wǎng)功能
      • 支持零配配網(wǎng)功能
      • 支持設(shè)備熱點(diǎn)批量配網(wǎng)功能
    • 芯片或模組的能力要求
      • 支持設(shè)備熱點(diǎn)開(kāi)啟狀態(tài)下接收Wi-Fi管理幀能力
      • 支持連接AP狀態(tài)下切信道發(fā)送Wi-Fi管理幀能力
      • 支持設(shè)備熱點(diǎn)批量配網(wǎng)的設(shè)備,設(shè)備熱點(diǎn)必須設(shè)置在1信道、6信道或11信道中
  3. 處理應(yīng)用中調(diào)用SDK功能模塊接口以及回調(diào)。
    1. 在應(yīng)用示例中的awss_open_dev_ap()函數(shù)中增加awss_dev_ap_reg_modeswit_cb()函數(shù)的調(diào)用。
      void awss_open_dev_ap(void *p)
      {
          iotx_event_regist_cb(linkkit_event_monitor);
          LOG("%s\n", __func__);
          if (netmgr_start(false) != 0) {
              aos_msleep(2000);
      #ifdef AWSS_BATCH_DEVAP_ENABLE
              awss_dev_ap_reg_modeswit_cb(awss_dev_ap_modeswitch_cb); //增加此調(diào)用
      #endif
              awss_dev_ap_start();
          }
          aos_task_exit(0);
      }
    2. 實(shí)現(xiàn)應(yīng)用層的回調(diào)函數(shù)awss_dev_ap_modeswitch_cb()
      #ifdef AWSS_BATCH_DEVAP_ENABLE
      #define DEV_AP_ZCONFIG_TIMEOUT_MS  120000 // (ms)
      extern void awss_set_config_press(uint8_t press);
      extern uint8_t awss_get_config_press(void);
      extern void zconfig_80211_frame_filter_set(uint8_t filter, uint8_t fix_channel);
      void do_awss_dev_ap();
      
      static aos_timer_t dev_ap_zconfig_timeout_timer;
      static uint8_t g_dev_ap_zconfig_timer = 0;   // this timer create once and can restart
      static uint8_t g_dev_ap_zconfig_run = 0;
      
      static void timer_func_devap_zconfig_timeout(void *arg1, void *arg2)
      {
          LOG("%s run\n", __func__);
      
          if (awss_get_config_press()) {
              // still in zero Wi-Fi provision stage, should stop and switch to dev ap
              do_awss_dev_ap();
          } else {
              // zero Wi-Fi provision finished
          }
      
          awss_set_config_press(0);
          zconfig_80211_frame_filter_set(0xFF, 0xFF);
          g_dev_ap_zconfig_run = 0;
          aos_timer_stop(&dev_ap_zconfig_timeout_timer);
      }
      
      static void awss_dev_ap_switch_to_zeroconfig(void *p)
      {
          LOG("%s run\n", __func__);
          // Stop dev ap Wi-Fi provision
          awss_dev_ap_stop();
          // Start and enable zero Wi-Fi provision
          iotx_event_regist_cb(linkkit_event_monitor);
          awss_set_config_press(1);
      
          // Start timer to count duration time of zero provision timeout
          if (!g_dev_ap_zconfig_timer) {
              aos_timer_new(&dev_ap_zconfig_timeout_timer, timer_func_devap_zconfig_timeout, NULL, DEV_AP_ZCONFIG_TIMEOUT_MS, 0);
              g_dev_ap_zconfig_timer = 1;
          }
          aos_timer_start(&dev_ap_zconfig_timeout_timer);
      
          // This will hold thread, when awss is going
          netmgr_start(true);
      
          LOG("%s exit\n", __func__);
          aos_task_exit(0);
      }
      
      int awss_dev_ap_modeswitch_cb(uint8_t awss_new_mode, uint8_t new_mode_timeout, uint8_t fix_channel)
      {
          if ((awss_new_mode == 0) && !g_dev_ap_zconfig_run) {
              g_dev_ap_zconfig_run = 1;
              // Only receive zero provision packets
              zconfig_80211_frame_filter_set(0x00, fix_channel);
              LOG("switch to awssmode %d, mode_timeout %d, chan %d\n", 0x00, new_mode_timeout, fix_channel);
              // switch to zero config
              aos_task_new("devap_to_zeroconfig", awss_dev_ap_switch_to_zeroconfig, NULL, 2048);
          }
      }
      #endif
  4. 編譯固件,并燒錄到設(shè)備中。

集成iOS App端

  1. 獲取SDK。
    確保配網(wǎng)SDK版本升級(jí)到1.11.0及以上,建議使用官網(wǎng)最新版本。

    您可以從生活物聯(lián)網(wǎng)平臺(tái)的控制臺(tái)下載SDK(請(qǐng)參見(jiàn)下載并集成SDK),也可以集成以下代碼。

    pod 'IMSDeviceCenter', '~>1.11.0'
  2. 開(kāi)始或停止批量發(fā)現(xiàn)。
    /**
     批量發(fā)現(xiàn)功能,通過(guò)已配網(wǎng)設(shè)備發(fā)現(xiàn)周邊其他設(shè)備,需特定設(shè)備支持
    
     @param targetProductKey 搜索目標(biāo)設(shè)備ProductKey,若為nil,則目標(biāo)為所有設(shè)備
     @param searcherProductKey 作為搜索者的已配網(wǎng)設(shè)備的ProductKey
     @param searchDeviceName 作為搜索者的已配網(wǎng)設(shè)備的DeviceName
     @param batchResultBlock 搜索到設(shè)備時(shí)觸發(fā)的回調(diào),會(huì)調(diào)用多次
     */
    - (void)startBatchDiscoveryForTargetProductKey:(NSString *) targetProductKey bySearcherProductKey:(NSString *) searcherProductKey deviceName:(NSString *) searchDeviceName resultBlock:(void(^)(NSArray * devices, NSError * err))batchResultBlock;
    
    /**
     停止已配網(wǎng)設(shè)備搜索周邊設(shè)備
     */
    - (void)stopBatchDiscovery;
  3. 開(kāi)始批量配網(wǎng)。
        IMLCandDeviceModel *model = [[IMLCandDeviceModel alloc] init];
        model.productKey = productKey; //待配網(wǎng)設(shè)備的ProductKey
        model.regProductKey = productKey; // 已配好設(shè)備的ProductKey
        model.regDeviceName = deviceName; // 已配好設(shè)備的DeviceName
        model.linkType = ForceAliLinkTypeZeroInBatches; //指定配網(wǎng)模式為批量配網(wǎng)
    
        [[IMLAddDeviceBiz sharedInstance] setDevice:model];
        [[IMLAddDeviceBiz sharedInstance] startAddDevice:notifier];
  4. 批量配網(wǎng)成功回調(diào)。
    與普通配網(wǎng)類(lèi)似,回調(diào)會(huì)通過(guò)notifyProvisionResult反饋。每成功配網(wǎng)一個(gè)設(shè)備就回調(diào)一次。若發(fā)生回調(diào)失敗,則表示此次批量配網(wǎng)全部失敗或者整體超時(shí)。
    /**
     通知上層UI:配網(wǎng)完成結(jié)果回調(diào)
    
     @param candDeviceModel 配網(wǎng)結(jié)果設(shè)備信息返回:配網(wǎng)失敗時(shí)為nil
     @param provisionError 錯(cuò)誤信息
     */
    - (void)notifyProvisionResult:(IMLCandDeviceModel *)candDeviceModel withProvisionError:(NSError *)provisionError;

集成Android App端

  1. 獲取SDK。

    您可以從生活物聯(lián)網(wǎng)平臺(tái)的控制臺(tái)下載SDK(請(qǐng)參見(jiàn)下載并集成SDK),也可以集成以下代碼。

    // maven倉(cāng)庫(kù)地址
    maven {
        url "http://maven.aliyun.com/nexus/content/repositories/releases"
    }
    
    api('com.aliyun.alink.linksdk:ilop-devicecenter:1.7.3')
  2. 開(kāi)始或停止批量發(fā)現(xiàn)。

    API reference 參見(jiàn) LocalDeviceMgr

    /**
     * 參數(shù)無(wú)效會(huì)拋出 IllegalArgumentException
     * @param context context
     * @param params {@link BatchDiscoveryParams}
     * @param listener discovery results, callback at least once
     */
    void startBatchDiscovery(Context context, BatchDiscoveryParams params, IDiscovery listener);
    
    /**
     * 停止批量配網(wǎng)
     * @param productKey 已配網(wǎng)設(shè)備ProductKey
     * @param deviceName 已配網(wǎng)設(shè)備DeviceName
     */
    void stopBatchDiscovery(String productKey, String deviceName);
  3. 開(kāi)始批量配網(wǎng)并監(jiān)聽(tīng)回調(diào)結(jié)果。

    startAddDevice各回調(diào)說(shuō)明參見(jiàn)配網(wǎng)SDK

    DeviceInfo info = new DeviceInfo();
    info.linkType = LinkType.ALI_ZERO_IN_BATCHES.getName();
    info.productKey = pk; // 待配網(wǎng)設(shè)備ProductKey
    info.regProductKey = regPk; // 已配網(wǎng)設(shè)備ProductKey
    info.regDeviceName = regdn; // 已配網(wǎng)設(shè)備DeviceName
    // 設(shè)置配網(wǎng)信息
    AddDeviceBiz.getInstance().setDevice(info);
    // 開(kāi)始批量配網(wǎng)
    AddDeviceBiz.getInstance().startAddDevice(context, new IAddDeviceListener() {
        @Override
        public void onPreCheck(boolean isSuccess, DCErrorCode dcErrorCode) {
            // 預(yù)檢查
        }
    
        @Override
        public void onProvisionPrepare(int prepareType) {
        }
    
        @Override
        public void onProvisioning() {
            // 配網(wǎng)中
        }
    
        @Override
        public void onProvisionStatus(ProvisionStatus provisionStatus) {
        }
    
        @Override
        public void onProvisionedResult(boolean isSuccess, DeviceInfo deviceInfo, DCErrorCode dcErrorCode) {
            // 配網(wǎng)結(jié)果回調(diào),每成功配網(wǎng)一個(gè)設(shè)備就回調(diào)一次。請(qǐng)您根據(jù)配網(wǎng)開(kāi)始時(shí)發(fā)現(xiàn)的設(shè)備列表和返回的配網(wǎng)成功的次數(shù)來(lái)判斷是否配網(wǎng)結(jié)束。
        }
    });