diff --git a/examples/common/app_reset/CMakeLists.txt b/examples/common/app_reset/CMakeLists.txt new file mode 100644 index 0000000..d29de8d --- /dev/null +++ b/examples/common/app_reset/CMakeLists.txt @@ -0,0 +1,3 @@ +idf_component_register(SRCS "app_reset.c" + INCLUDE_DIRS "." + REQUIRES button esp_rainmaker) diff --git a/examples/common/app_reset/app_reset.c b/examples/common/app_reset/app_reset.c new file mode 100644 index 0000000..b330711 --- /dev/null +++ b/examples/common/app_reset/app_reset.c @@ -0,0 +1,65 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +/* It is recommended to copy this code in your example so that you can modify as + * per your application's needs, especially for the indicator calbacks, + * wifi_reset_indicate() and factory_reset_indicate(). + */ +#include +#include +#include +#include + +static const char *TAG = "app_reset"; + +#define REBOOT_DELAY 2 + +static void wifi_reset_trigger(void *arg) +{ + esp_rmaker_wifi_reset(REBOOT_DELAY); +} + +static void wifi_reset_indicate(void *arg) +{ + ESP_LOGI(TAG, "Release button now for Wi-Fi reset. Keep pressed for factory reset."); +} + +static void factory_reset_trigger(void *arg) +{ + esp_rmaker_factory_reset(REBOOT_DELAY); +} + +static void factory_reset_indicate(void *arg) +{ + ESP_LOGI(TAG, "Release button to trigger factory reset."); +} + +esp_err_t app_reset_button_register(button_handle_t btn_handle, uint8_t wifi_reset_timeout, + uint8_t factory_reset_timeout) +{ + if (!btn_handle) { + return ESP_ERR_INVALID_ARG; + } + if (wifi_reset_timeout) { + iot_button_add_on_release_cb(btn_handle, wifi_reset_timeout, wifi_reset_trigger, NULL); + iot_button_add_on_press_cb(btn_handle, wifi_reset_timeout, wifi_reset_indicate, NULL); + } + if (factory_reset_timeout) { + if (factory_reset_timeout <= wifi_reset_timeout) { + ESP_LOGW(TAG, "It is recommended to have factory_reset_timeout > wifi_reset_timeout"); + } + iot_button_add_on_release_cb(btn_handle, factory_reset_timeout, factory_reset_trigger, NULL); + iot_button_add_on_press_cb(btn_handle, factory_reset_timeout, factory_reset_indicate, NULL); + } + return ESP_OK; +} + +button_handle_t app_reset_button_create(gpio_num_t gpio_num, button_active_t active_level) +{ + return iot_button_create(gpio_num, active_level); +} diff --git a/examples/common/app_reset/app_reset.h b/examples/common/app_reset/app_reset.h new file mode 100644 index 0000000..53c54d3 --- /dev/null +++ b/examples/common/app_reset/app_reset.h @@ -0,0 +1,42 @@ +/* + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ +#pragma once +#include +#include +#include + +/** Create a button handle + * + * This is just a wrapper over iot_button_create(). This can be used to register + * Wi-Fi/Factory reset functionality for a button. + * + * @param[in] gpio_num GPIO index of the pin that the button uses. + * @param[in] active_level button hardware active level. + * "BUTTON_ACTIVE_LOW" means that when the button is pressed, the GPIO will read low level. + * For "BUTTON_ACTIVE_HIGH", it will be reverse. + * + * @return A button_handle_t handle to the created button object, or NULL in case of error. + */ +button_handle_t app_reset_button_create(gpio_num_t gpio_num, button_active_t active_level); + +/** Register callbacks for Wi-Fi/Factory reset + * + * Register Wi-Fi reset or factory reset functionality on a button. + * If you want to use different buttons for these two, call this API twice, with appropriate + * button handles. + * + * @param[in] btn_handle Button handle returned by iot_button_create() or app_button_create() + * @param[in] wifi_reset_timeout Timeout after which the Wi-Fi reset should be triggered. Set to 0, + * if you do not want Wi-Fi reset. + * @param[in] factory_reset_timeout Timeout after which the factory reset should be triggered. Set to 0, + * if you do not want factory reset. + * + * @return ESP_OK on success. + * @return error in case of failure. + */ +esp_err_t app_reset_button_register(button_handle_t btn_handle, uint8_t wifi_reset_timeout, uint8_t factory_reset_timeout); diff --git a/examples/common/app_reset/component.mk b/examples/common/app_reset/component.mk new file mode 100644 index 0000000..2ec0e78 --- /dev/null +++ b/examples/common/app_reset/component.mk @@ -0,0 +1,2 @@ +COMPONENT_ADD_INCLUDEDIRS := . +COMPONENT_SRCDIRS := . diff --git a/examples/fan/main/app_driver.c b/examples/fan/main/app_driver.c index 252a7c8..5a47fd5 100644 --- a/examples/fan/main/app_driver.c +++ b/examples/fan/main/app_driver.c @@ -8,10 +8,7 @@ */ #include -#include -#include #include -#include #include #include @@ -20,6 +17,7 @@ #include #include +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -33,6 +31,9 @@ #define DEFAULT_SATURATION 100 #define DEFAULT_BRIGHTNESS ( 20 * DEFAULT_SPEED) +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 + static uint8_t g_speed = DEFAULT_SPEED; static uint16_t g_hue = DEFAULT_HUE; static uint16_t g_saturation = DEFAULT_SATURATION; @@ -173,19 +174,14 @@ static void push_btn_cb(void *arg) } } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} - void app_driver_init() { app_fan_init(); button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); if (btn_handle) { - iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, push_btn_cb, "RELEASE"); - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); + /* Register a callback for a button tap (short press) event */ + iot_button_set_evt_cb(btn_handle, BUTTON_CB_TAP, push_btn_cb, NULL); + /* Register Wi-Fi reset and factory reset functionality on same button */ + app_reset_button_register(btn_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); } } diff --git a/examples/gpio/main/app_driver.c b/examples/gpio/main/app_driver.c index 88dba62..e662f84 100644 --- a/examples/gpio/main/app_driver.c +++ b/examples/gpio/main/app_driver.c @@ -9,13 +9,9 @@ #include #include -#include -#include -#include #include -#include - +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -28,6 +24,9 @@ #define OUTPUT_GPIO_GREEN 14ULL #define OUTPUT_GPIO_BLUE 15ULL +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 + esp_err_t app_driver_set_gpio(const char *name, bool state) { if (strcmp(name, "Red") == 0) { @@ -41,19 +40,11 @@ esp_err_t app_driver_set_gpio(const char *name, bool state) } return ESP_OK; } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} void app_driver_init() { - button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); - if (btn_handle) { - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); - } + app_reset_button_register(app_reset_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL), + WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); /* Configure power */ gpio_config_t io_conf = { diff --git a/examples/led_light/main/app_driver.c b/examples/led_light/main/app_driver.c index bc20b43..26195e1 100644 --- a/examples/led_light/main/app_driver.c +++ b/examples/led_light/main/app_driver.c @@ -8,10 +8,8 @@ */ #include -#include -#include #include -#include +#include #include #include @@ -20,6 +18,7 @@ #include #include +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -29,6 +28,8 @@ /* This is the GPIO on which the power will be set */ #define OUTPUT_GPIO 19 +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 static uint16_t g_hue = DEFAULT_HUE; static uint16_t g_saturation = DEFAULT_SATURATION; @@ -173,19 +174,14 @@ static void push_btn_cb(void *arg) esp_rmaker_bool(g_power)); } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} - void app_driver_init() { app_light_init(); button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); if (btn_handle) { - iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, push_btn_cb, "RELEASE"); - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); + /* Register a callback for a button tap (short press) event */ + iot_button_set_evt_cb(btn_handle, BUTTON_CB_TAP, push_btn_cb, NULL); + /* Register Wi-Fi reset and factory reset functionality on same button */ + app_reset_button_register(btn_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); } } diff --git a/examples/multi_device/main/app_driver.c b/examples/multi_device/main/app_driver.c index 05a9123..6f642a6 100644 --- a/examples/multi_device/main/app_driver.c +++ b/examples/multi_device/main/app_driver.c @@ -7,10 +7,7 @@ */ #include -#include -#include #include -#include #include #include @@ -19,6 +16,7 @@ #include #include +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -35,6 +33,9 @@ static const char *TAG = "app_driver"; #define DEFAULT_GREEN 25 #define DEFAULT_BLUE 0 +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 + static bool g_power_state = DEFAULT_SWITCH_POWER; static float g_temperature = DEFAULT_TEMPERATURE; static esp_timer_handle_t sensor_timer; @@ -114,13 +115,6 @@ static void push_btn_cb(void *arg) esp_rmaker_bool(new_state)); } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} - static void set_power_state(bool target) { gpio_set_level(OUTPUT_GPIO, target); @@ -131,8 +125,10 @@ void app_driver_init() { button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); if (btn_handle) { - iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, push_btn_cb, "RELEASE"); - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); + /* Register a callback for a button tap (short press) event */ + iot_button_set_evt_cb(btn_handle, BUTTON_CB_TAP, push_btn_cb, NULL); + /* Register Wi-Fi reset and factory reset functionality on same button */ + app_reset_button_register(btn_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); } /* Configure power */ diff --git a/examples/switch/main/app_driver.c b/examples/switch/main/app_driver.c index 1b870b8..5b56fc8 100644 --- a/examples/switch/main/app_driver.c +++ b/examples/switch/main/app_driver.c @@ -8,10 +8,7 @@ */ #include -#include -#include #include -#include #include #include @@ -19,6 +16,7 @@ #include #include +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -35,6 +33,9 @@ static const char *TAG = "app_driver"; #define DEFAULT_GREEN 25 #define DEFAULT_BLUE 0 +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 + static void app_indicator_set(bool state) { if (!strip) { @@ -76,12 +77,6 @@ static void push_btn_cb(void *arg) esp_rmaker_bool(new_state)); } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} static void set_power_state(bool target) { gpio_set_level(OUTPUT_GPIO, target); @@ -92,8 +87,10 @@ void app_driver_init() { button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); if (btn_handle) { - iot_button_set_evt_cb(btn_handle, BUTTON_CB_RELEASE, push_btn_cb, "RELEASE"); - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); + /* Register a callback for a button tap (short press) event */ + iot_button_set_evt_cb(btn_handle, BUTTON_CB_TAP, push_btn_cb, NULL); + /* Register Wi-Fi reset and factory reset functionality on same button */ + app_reset_button_register(btn_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); } /* Configure power */ diff --git a/examples/switch/main/app_main.c b/examples/switch/main/app_main.c index 37d99d1..9473dbb 100644 --- a/examples/switch/main/app_main.c +++ b/examples/switch/main/app_main.c @@ -59,6 +59,15 @@ static void event_handler(void* arg, esp_event_base_t event_base, case RMAKER_EVENT_CLAIM_FAILED: ESP_LOGI(TAG, "RainMaker Claim Failed."); break; + case RMAKER_EVENT_REBOOT: + ESP_LOGI(TAG, "Rebooting in %d seconds.", *((uint8_t *)event_data)); + break; + case RMAKER_EVENT_WIFI_RESET: + ESP_LOGI(TAG, "Wi-Fi credentials reset."); + break; + case RMAKER_EVENT_FACTORY_RESET: + ESP_LOGI(TAG, "Node reset to factory defaults."); + break; default: ESP_LOGW(TAG, "Unhandled RainMaker Event: %d", event_id); } diff --git a/examples/temperature_sensor/main/app_driver.c b/examples/temperature_sensor/main/app_driver.c index fc8ae4f..14a423c 100644 --- a/examples/temperature_sensor/main/app_driver.c +++ b/examples/temperature_sensor/main/app_driver.c @@ -8,18 +8,15 @@ */ #include -#include -#include #include -#include #include -#include #include #include #include #include +#include #include "app_priv.h" #define RMT_TX_CHANNEL RMT_CHANNEL_0 @@ -32,6 +29,9 @@ #define DEFAULT_SATURATION 100 #define DEFAULT_BRIGHTNESS 50 +#define WIFI_RESET_BUTTON_TIMEOUT 3 +#define FACTORY_RESET_BUTTON_TIMEOUT 10 + static led_strip_t *g_strip; static uint16_t g_hue; static uint16_t g_saturation = DEFAULT_SATURATION; @@ -160,18 +160,9 @@ esp_err_t app_sensor_init(void) return ESP_FAIL; } -static void button_press_3sec_cb(void *arg) -{ - nvs_flash_deinit(); - nvs_flash_erase(); - esp_restart(); -} - void app_driver_init() { app_sensor_init(); - button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); - if (btn_handle) { - iot_button_add_on_press_cb(btn_handle, 3, button_press_3sec_cb, NULL); - } + app_reset_button_register(app_reset_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL), + WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); }