T2-U设备配网、重置与网络状态

基于 TuyaOS 的开发板,如 T2 等


Post Reply
User avatar
chenyisong
Posts: 124

TuyaOS 联网单品种的 Wi-Fi 设备需要连接路由器,并且连接到涂鸦云,才能实现正常智能控制。这样智能设备就会涉及到 以下相关流程:

  • 设备配网及涂鸦云激活
  • 已配网/已激活设备重置,重新进入配网状态
  • 当前网络状态显示

一、 设备配网

TuyaOS 开发框架提供了很多设备配网方案,例如 热点配网蓝牙配网闪电配网 等。T2-U 开发板当前 SDK 支持 热点配网蓝牙配网 这 2 种配网模式,设备配网模式的配置包含了选择设备 配网模式 和选择 配网启动方式

通过 APP 配网连接路由器后,设备自动会在涂鸦云激活,并与当前配网的用户账号做绑定。

1. 设备配网模式

TuyaOS 开发框架提供多种设备配网模式,主要通过 tuya_iot_wf_soc_dev_init_param() 函数第一个参数 GW_WF_CFG_MTHD_SEL cfg 设置。

Code: Select all

/* tuya sdk definition of wifi work mode */
typedef BYTE_T GW_WF_CFG_MTHD_SEL; // wifi config method select
#define GWCM_OLD                0   // do not have low power mode
#define GWCM_LOW_POWER          1   // with low power mode
#define GWCM_SPCL_MODE          2   // special with low power mode
#define GWCM_OLD_PROD           3   // GWCM_OLD mode with product
#define GWCM_LOW_POWER_AUTOCFG 4   // with low power mode && auto cfg
#define GWCM_SPCL_AUTOCFG       5   // special with low power mode && auto cfg

配网模式的定义

注意:

配网模式中涉及到的低功耗,是指关闭射频模组,芯片并非进入了睡眠模式。低功耗状态下无法正常配网,需要通过外部条件触发手工调用

宏定义配网模式备注说明
GWCM_OLD / GWCM_OLD_PROD上电配网GWCM_OLD_PROD 模式在启动时会扫描成品产测的指定信标。<br>在 TuyaOS 3.0.0 及以上的版本里,扫描成品产测信标的功能由应用自行实现。
GWCM_LOW_POWER上电低功耗-
GWCM_SPCL_MODE上电低功耗和记忆重连-
GWCM_LOW_POWER_AUTOCFG上电配网和低功耗-
GWCM_SPCL_AUTOCFG上电配网和低功耗和记忆重连-

下面依次介绍上诉配网模式的区别:

  • 上电配网

    设备状态<div style="width:150px"></div>描述
    未配网上电就进入待配网状态
    待配网/配网中一直处于待配网状态
    配网激活后被移除进入待配网状态
  • 上电低功耗

    设备状态<div style="width:150px"></div>描述
    未配网上电默认低功耗状态,需调用 重置接口 才能进入配网状态
    待配网/配网中一段时间后(默认 3 min,您可以自定义)没有配网成功,设备自动进入低功耗状态。这时,如果重启设备,重启后的状态为:<ul><li> 配网时间小于 10 秒,保持上次配网状态 </li><li> 配网时间超过 10 秒,进入低功耗 </li></ul>
    配网激活后被移除进入配网状态
  • 上电配网和低功耗

    设备状态 <div style="width:150px"></div>描述
    未配网上电就进入配网状态
    待配网/配网中一段时间后(默认 3 min,您可以自定义)没有配网成功,设备自动进入低功耗状态
    配网激活后被移除进入配网状态
  • 上电低功耗和记忆重连

    设备状态 <div style="width:150px"></div>描述
    未配网上电默认低功耗状态,需调用 重置接口 才能进入配网状态
    待配网/配网中<ul><li> 本地移除后进入配网状态:一段时间后(默认 3 min,您可以自定义)没有配网成功,设备连接被移除前所连接的路由器(记忆重连)。这时,如果重启设备,重启后的状态为:<ul><li> 配网时间小于 10 秒,保持上次配网状态 </li><li> 配网时间超过 10 秒,连接被移除前所连接的路由器(记忆重连) </li></ul> </li><li> 从未配网切换到配网状态或者远程移除进入配网状态:一段时间后(默认 3 min,您可以自定义)没有配网成功,设备自动进入低功耗状态。这时,如果重启设备,重启后的状态为:<ul><li> 配网时间小于 10 秒,保持上次配网状态 </li><li> 配网时间超过 10 秒,进入低功耗 </li></ul> </li></ul>
    配网激活后被移除进入配网状态<br/>
  • 上电配网、低功耗和记忆重连

    设备状态 <div style="width:150px"></div>描述
    未配网上电就进入配网状态
    待配网/配网中<ul><li> 本地移除后进入配网状态:一段时间后(默认 3 min,您可以自定义)没有配网成功,设备连接被移除前所连接的路由器(记忆重连)这时,如果重启设备,重启后的状态为:<ul><li> 配网时间小于 10 秒,保持上次配网状态 </li><li> 配网时间超过 10 秒,连接被移除前所连接的路由器(记忆重连) </li></ul> </li><li> 从未配网切换到配网状态或者远程移除进入配网状态:一段时间后(默认 3 min,您可以自定义)没有配网成功,设备自动进入低功耗状态。这时,如果重启设备,重启后的状态为:<ul><li> 配网时间小于 10 秒,保持上次配网状态 </li><li> 配网时间超过 10 秒,进入低功耗 </li></ul> </li></ul> </li></ul>
    配网激活后被移除进入配网状态<br/>

2. 配网启动方式

TuyaOS 开发框架提供多种设备初始配网启动方式:

配网启动方式 <div style="width:150px"></div>描述
仅支持热点模式配网仅支持 热点模式配网,调用设备重置接口后设备启动还是热点配网
仅支持快连模式配网仅支持快连模式配网,调用设备重置接口后,还是快连模式配网
默认启动热点模式配网设备启动默认先进入热点模式配网,调用设备重置接口后会进入快连模式配网,以此循环
默认启动快连模式配网设备启动默认先进入快连模式配网,调用设备重置接口后进入热点模式配网,以此循环
万能配网任何配网方式都生效,热点模式配网,快连模式配网,闪电配网FFS 配网

配网启动方式主要通过 tuya_iot_wf_soc_dev_init_param() 函数第二个参数 GW_WF_START_MODE start_mode 设置。

Code: Select all

/* tuya sdk definition of wifi start mode */
typedef BYTE_T GW_WF_START_MODE;
#define WF_START_AP_ONLY        0   // only have ap-cfg mode
#define WF_START_SMART_ONLY     1   // only have smart-cfg mode
#define WF_START_AP_FIRST       2   // have both ap-cfg and smart-cfg. default is ap-cfg mode
#define WF_START_SMART_FIRST    3   // have both ap-cfg and smart-cfg. default is smart-cfg mode
#define WF_START_SMART_AP_CONCURRENT    4   // ap-cfg and smart-cfg is concurrent

配网启动方式的定义

宏定义配网启动方式备注说明
WF_START_AP_ONLY仅支持热点模式配网-
WF_START_SMART_ONLY仅支持快连模式配网Tuyaos 3.4.0 及以上版本的框架不支持快连模式配网。<br>会被当成万能配网做兼容处理。
WF_START_AP_FIRST默认启动热点模式配网-
WF_START_SMART_FIRST默认启动快连模式配网Tuyaos 3.4.0 及以上版本的框架不支持快连模式配网。<br>故该启动方式会被当成万能配网做兼容处理。
WF_START_SMART_AP_CONCURRENT万能配网-

注意:

  1. Tuyaos 3.4.0 及以上版本不再支持快连模式配网,如果用户选择 默认启动热点模式配网默认启动快连模式配网 这两种启动方式,TuyaOS 默认使用 万能配网 的启动方式做兼容处理。
  2. 蓝牙配网 独立于任何一种配网方式,只要蓝牙服务及蓝牙配网功能是打开的,配网功能被启动时,框架会自动开启蓝牙配网功能。

TuyaOS 开发框架支持的配网模式,可以点击以下链接详细了解:

3. 配网超时时间设置

可通过该接口设置设备保持配网状态的时间。如果在该时间内设备没有配网成功,开发框架会停止配网,根据配网模式的设置进入相应的状态。

Code: Select all

/**

 * @brief Set wifi netcfg timeout value in seconds
 *
 * @param[in] timeout_s time out value of netcfg.
 *
 * @return OPRT_OK on success. Others on error, please refer to tuya_error_code.h
 */

VOID set_wf_netcfg_timeout(UINT_T timeout_s);

二、 网络状态获取

网络状态 通过 tuya_iot_reg_get_wf_nw_stat_cb(__soc_dev_net_status_cb) 接口设置网络状态变化回调。设备网络状态变化的时候,TuyaOS 框架会调用该 API 注册进来的回调函数通知应用进行相应的处理。

TuyaOS 默认每 1 秒钟查询一次设备的网络状态,如果网络状态发生了变化,TuyaOS 会调用注册的回调接口,将变化通知给应用程序。

Code: Select all

 /**
 * @brief tuya_iot_reg_get_wf_nw_stat_cb_params
 *
 * @param wf_nw_stat_cb
 * @param min_interval_s
 *
 * @return
 */
OPERATE_RET tuya_iot_reg_get_wf_nw_stat_cb_params(IN CONST GET_WF_NW_STAT_CB wf_nw_stat_cb, IN CONST INT_T min_interval_s);
#define tuya_iot_reg_get_wf_nw_stat_cb(wf_nw_stat_cb) \
    tuya_iot_reg_get_wf_nw_stat_cb_params(wf_nw_stat_cb, 1)

GET_WF_NW_STAT_CB wf_nw_stat_cb:网络状态变化通知回调,按照min_interval_s周期,检测网络状态,如果发生变化则会调用改回调接口。

示例回调:

Code: Select all

/**
* @brief  SOC external network status change callback
*
* @param[in] stat: curr network status
* 
* @return none
*/
STATIC VOID __soc_dev_net_status_cb(IN CONST GW_WIFI_NW_STAT_E stat)
{
    TAL_PR_DEBUG("network status:%d", stat);
    if (STAT_CLOUD_CONN == stat) {
       /* 网络状态指示 */
    }
}

TuyaOS 定义的网络状态有以下几种:

Code: Select all

/* tuya sdk definition of wifi-net status */
typedef BYTE_T GW_WIFI_NW_STAT_E;
#define STAT_LOW_POWER          0   // idle status,use to external config network
#define STAT_UNPROVISION        1   // smart config status
#define STAT_AP_STA_UNCFG       2   // ap WIFI config status
#define STAT_AP_STA_DISC        3   // ap WIFI already config,station disconnect
#define STAT_AP_STA_CONN        4   // ap station mode,station connect
#define STAT_STA_DISC           5   // only station mode,disconnect
#define STAT_STA_CONN           6   // station mode connect
#define STAT_CLOUD_CONN         7   // cloud connect
#define STAT_AP_CLOUD_CONN      8   // cloud connect and ap start
#define STAT_REG_FAIL           9   // register fail
#define STAT_OFFLINE            10   // offline
#define STAT_MQTT_ONLINE        11
#define STAT_MQTT_OFFLINE       12
#define STAT_UNPROVISION_AP_STA_UNCFG		13 //smart-cfg and ap-cfg concurrent config status
#define STAT_BT_ACTIVED         14

三、设备重置

设备重置是把设备恢复到配网、激活之前状态的操作。根据触发源不同,可以分为:

  • 本地重置
  • 远程重置

根据重置后设备所处的状态,又可细分为:

  • 普通重置:指解除绑定
  • 恢复出厂重置:指解除绑定清除数据

设备重置的时候,还会和设备配网模式关联起来,具体细节请参考 设备配网模式

设备重置主要适用场景如下:

  • 让设备进入配网状态:如支持 记忆模式 的设备,通过设备重置功能进入配网状态。
  • 让设备退网/解除绑定:如设备需要更换连接的路由器。
  • 让设备恢复出厂/清除用户数据:如电工类产品,清除设备本地存储的电量计量数据。

注意:

对于支持 Wi-Fi 网络备份闪电配网 的设备,无需执行设备重置即可完成路由器变更。

TuyaOS 开发框架执行完自身的重置任务后会通过回调函数通知开发者设备被重置了,方便开发者在回调中执行自定义的重置行为。最后开发框架会调用 Reset 接口重启设备。设备重启完成后就会进入对应的配网状态。

1. 功能描述

  • 普通重置(解除绑定):
    • 清除本地保存的配网数据
    • 清除本地保存的定时数据
    • 通知云端执行解绑操作(云端不会清除设备的历史数据,如定时数据、设备名称等,再次配网绑定后用户可查看到)
    • 通过回调函数通知用户
  • 恢复出厂重置(解绑并清除数据):
    • 全部 普通重置 的数据
    • 通过回调函数通知用户
    • 本地保存的描述设备 DP 列表 (schema) 的数据
    • 通知云端执行解绑并清除数据(云端会清除设备的历史数据,相当于是全新的设备)
    • 通过回调函数通知用户

2. 相关接口

  • 本地重置时,需要应用主动调用下述 API
    • 普通重置(解除绑定):tuya_iot_wf_gw_unactive
    • 恢复出厂重置(解绑并清除数据):tuya_iot_wf_gw_reset
  • 远程重置时,开发者无需主动调用 API,开发框架会监听云端下发的指令,执行重置操作。
  • 本地重置和远程重置时,开发框架都会通过回调函数通知开发者。通知回调函数的注册可见设备初始化的 [IoT 设备功能回调函数](https://developer.tuya.com/cn/docs/iot- ... itle-9-IoT 设备功能回调函数)。

重置通知回调

重置通知回调函数,由应用通过设备初始化接口传入。无论何种重置方式,回调函数都会被调用,以执行自定义重置行为(如清除应用数据)。

Code: Select all

/**
 * @brief Handler to process gateway reset
 *
 * @param[in] type Reset type, see GW_RESET_TYPE_E
 */
typedef VOID (*GW_RESET_IFM_CB)(GW_RESET_TYPE_E type);
  • 回调参数数据定义

Code: Select all

typedef enum {
    GW_LOCAL_RESET_FACTORY = 0,    // 本地恢复出厂重置
    GW_REMOTE_UNACTIVE,                // App 普通重置(解除绑定)
    GW_LOCAL_UNACTIVE,                   // 本地普通重置(解除绑定)
    GW_REMOTE_RESET_FACTORY,       // App 恢复出厂重置
    GW_RESET_DATA_FACTORY,            // 激活时数据重置(详见 FAQ)
} GW_RESET_TYPE_E;

本地普通重置

开发者调用 tuya_iot_wf_gw_unactive() 函数完成本地普通重置, 该 API 会立即返回,具体重置操作将 异步执行,完成重置后将通过回调函数通知开发者。

Code: Select all

/**
 * @brief Local unactive
 *
 * @return OPERATE_RET
 */
OPERATE_RET tuya_iot_wf_gw_unactive(VOID);

本地恢复出厂重置(解绑并清除数据)

开发者调用 tuya_iot_wf_gw_reset() 函数完成本地恢复出厂重置(解绑并清除数据),该 API 会立即返回,具体重置操作将 异步执行,完成重置后将通过回调函数通知开发者。

Code: Select all

/**
 * @brief Local reset factory
 *
 * @return OPERATE_RET
 */
OPERATE_RET tuya_iot_wf_gw_reset(VOID);

本地快速重置(解除绑定)

开发者调用 tuya_iot_wf_gw_fast_unactive() 函数完成本地快速重置(接触绑定),该 API 同步执行 重置操作,在重置之后设备会重新启动,并且按照新的 mthdwifi_start_mode 进入配网状态。

Code: Select all

/**
 * @brief Local fast unactive
 *
 * @param[in] mthd: new work mode after reboot
 * @param[in] wifi_start_mode: new netcfg mode after reboot
 *
 * @return OPERATE_RET
 */
OPERATE_RET tuya_iot_wf_gw_fast_unactive(GW_WF_CFG_MTHD_SEL mthd, GW_WF_START_MODE wifi_start_mode);

注意:

该 API 用于快速重置设备并重启,在 设备初始化 前调用。mthdwifi_start_mode 的具体细节见 设备配网模式

3. 设备重置接口使用示例

Code: Select all


// 执行自定义重置行为
VOID __reset_cb(GW_RESET_TYPE_E type)
{
    if(GW_LOCAL_RESET_FACTORY == type) { // 本地恢复出厂重置

    } else if(GW_REMOTE_UNACTIVE == type) { // App 普通重置(解除绑定)

    } else if(GW_LOCAL_UNACTIVE == type) { // 本地普通重置(解除绑定)

    } else if(GW_REMOTE_RESET_FACTORY == type) { // App 恢复出厂重置

    } else if(GW_RESET_DATA_FACTORY == type) { // 激活时数据重置(详见 FAQ)

    }
}

// 设备初始化
int test_dev_init()
{
    TY_IOT_CBS_S cbs = {
        .gw_reset_cb = __reset_cb,
        //其他回调函数设置
    };


    // 调用设备初始化 API,把 cbs 传入
    // xxx
}

// 本地普通重置
void test_local_unactive()
{
    TUYA_CALL_ERR_LOG(tuya_iot_wf_gw_unactive());
}

// 本地恢复出厂重置
void test_local_reset()
{
    TUYA_CALL_ERR_LOG(tuya_iot_wf_gw_reset());
}

设备重置FAQ可点击以下链接了解:

https://developer.tuya.com/cn/docs/iot-device-dev/TuyaOS-iot_abi_device_reset?id=Kc67srci7m1jk#title-17-FAQ

四、示例

在 tuyaos_demo_quickstart 示例中,自带了按钮驱动 app_key.c 和 指示灯驱动 app_led.c 示例代码供参考

默认的配网按钮和网络状态指示灯为:

丝印名称备注
P26LED 引脚,高电平点亮
P7按键引脚,低电平有效,短按切换指示灯状态,长按进入配网状态

可以在 tuya_app_main.c 中修改

Code: Select all

/* network button, LED pin */
#define KEY_PIN 7
#define LED_PIN 26

1. 重置

tuyaos_demo_quickstart 示例中是通过按钮长按 5 秒后调用 tuya_iot_wf_gw_unactive 让设备进入普通重置(解除绑定)状态

Code: Select all

STATIC VOID_T app_key_task(VOID_T *args)
{
    OPERATE_RET op_ret = OPRT_OK;
    TUYA_GPIO_LEVEL_E read_level = TUYA_GPIO_LEVEL_HIGH;
    UINT32_T time_start = 0, timer_end = 0;

    for (;;) {
        tkl_gpio_read(sg_key_pin_id, &read_level);
        if (TUYA_GPIO_LEVEL_LOW == read_level) {
            tal_system_sleep(3);
            tkl_gpio_read(sg_key_pin_id, &read_level);
            if (TUYA_GPIO_LEVEL_LOW != read_level) {
                break; // jitter
            }

            time_start = tal_system_get_millisecond();
            while (TUYA_GPIO_LEVEL_LOW == read_level) {
                tal_system_sleep(30);
                tkl_gpio_read(sg_key_pin_id, &read_level);
                timer_end = tal_system_get_millisecond();

                if (timer_end - time_start >= LONE_PRESS_TIME) {
                    TAL_PR_DEBUG("long press, remove device");
                    /* long press, remove device */
                    op_ret = tuya_iot_wf_gw_unactive();
                    if (op_ret != OPRT_OK) {
                        TAL_PR_ERR("long press tuya_iot_wf_gw_unactive error, %d", op_ret);
                    }
                    break;
                }
            }

            if (timer_end - time_start > 50) {
                TAL_PR_DEBUG("normal press");
                /* normal press */
                if (get_led_status()) {
                    set_led_status(LED_OFF);
                }
                else {
                    set_led_status(LED_ON);
                }
                update_all_dp();
            } else {
                TAL_PR_DEBUG("time too short");
            }
        }

        tal_system_sleep(100);
    }

    return;
}

2. 设备重启

tuyaos_demo_quickstart 示例中是 在设备初始化时将 __soc_dev_restart_req_cb 回调注册至 TuyaOS,并在回调中调用tal_system_reset()完成重启。

Code: Select all

/**
 * @brief SOC device process restart request entry
 *
 * @param[in] type: gateway reset type
 *
 * @return none
 */
STATIC VOID_T __soc_dev_restart_req_cb(GW_RESET_TYPE_E type)
{
    TAL_PR_DEBUG("SOC Rev Restart Req %d", type);
    if (GW_RESET_DATA_FACTORY != type) {
        // UserTODO Device process restart
        tal_system_reset();
    }

    return;
}
Post Reply