生活物聯(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í)序圖如下所示。
- 設(shè)備上電或操作設(shè)備按鍵,將所有待添加的設(shè)備進(jìn)入設(shè)備熱點(diǎn)配網(wǎng)模式。
- 通過(guò)App對(duì)其中一個(gè)設(shè)備進(jìn)行設(shè)備熱點(diǎn)配網(wǎng),并完成配網(wǎng)及綁定操作。調(diào)用的SDK請(qǐng)參見(jiàn)Android App SDK和iOS App SDK。
- 指定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è)備信息。
- 3中返回的其他待配網(wǎng)設(shè)備,通過(guò)零配配網(wǎng)方式完成配網(wǎng),并在App SDK回調(diào)中會(huì)反饋配網(wǎng)結(jié)果。
集成設(shè)備端
- 獲取生活物聯(lián)網(wǎng)平臺(tái)SDK V1.3.0及以上版本。請(qǐng)參見(jiàn)SDK概述與開(kāi)發(fā)環(huán)境設(shè)置。
- 使能SDK中功能模塊。
在應(yīng)用的mk文件中增加配置項(xiàng)GLOBAL_CFLAGS += -DAWSS_BATCH_DEVAP_ENABLE
。如您基于living_platform開(kāi)發(fā),在living_platform.mk文件中已包含該配置項(xiàng),如下圖所示。
設(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信道中
- 處理應(yīng)用中調(diào)用SDK功能模塊接口以及回調(diào)。
- 在應(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);
}
- 實(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
- 編譯固件,并燒錄到設(shè)備中。
集成iOS App端
- 獲取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'
- 開(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;
- 開(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];
- 批量配網(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端
- 獲取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')
- 開(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);
- 開(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é)束。
}
});