482 lines
20 KiB
C
482 lines
20 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include <string.h>
|
|
#include <freertos/FreeRTOS.h>
|
|
#include <freertos/task.h>
|
|
#include "freertos/timers.h"
|
|
|
|
#include <esp_log.h>
|
|
#include <nvs_flash.h>
|
|
|
|
#include "ping/ping_sock.h"
|
|
#include "lwip/inet.h"
|
|
#include "lwip/netdb.h"
|
|
#include "lwip/sockets.h"
|
|
|
|
#include <esp_rmaker_core.h>
|
|
#include <esp_rmaker_standard_params.h>
|
|
#include <esp_rmaker_standard_devices.h>
|
|
#include <esp_rmaker_schedule.h>
|
|
#include <esp_rmaker_scenes.h>
|
|
#include <esp_rmaker_utils.h>
|
|
#include <esp_rmaker_core.h>
|
|
#include <esp_rmaker_common_events.h>
|
|
#include <esp_rmaker_standard_types.h>
|
|
|
|
#include <app_wifi.h>
|
|
#include <app_reset.h>
|
|
#include "led_strip.h"
|
|
#include <iot_button.h>
|
|
|
|
#include "esp_radar.h"
|
|
#include "esp_ping.h"
|
|
|
|
#if CONFIG_IDF_TARGET_ESP32C5
|
|
#define WS2812_GPIO 27
|
|
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61
|
|
#define WS2812_GPIO 8
|
|
#elif CONFIG_IDF_TARGET_ESP32S3
|
|
#define WS2812_GPIO 38
|
|
#elif CONFIG_IDF_TARGET_ESP32S2
|
|
#define WS2812_GPIO 18
|
|
#elif CONFIG_IDF_TARGET_ESP32C3
|
|
#define WS2812_GPIO 8
|
|
#endif
|
|
|
|
#ifdef CONFIG_IDF_TARGET_ESP32C3
|
|
#define BUTTON_GPIO GPIO_NUM_8
|
|
#else
|
|
#define BUTTON_GPIO GPIO_NUM_0
|
|
#endif
|
|
|
|
#define BUTTON_WIFI_RESET_TIMEOUT 3
|
|
#define BUTTON_FACTORY_RESET_TIMEOUT 5
|
|
#define AUTO_CALIBRATE_RAPORT_INTERVAL 5
|
|
|
|
#define RADAR_PING_DATA_INTERVAL 10
|
|
#define RADAR_DETECT_BUFF_MAX_SIZE 16
|
|
#define RADAR_PARAM_SOMEONE_STATUS "someone_status"
|
|
#define RADAR_PARAM_SOMEONE_TIMEOUT "someone_timeout"
|
|
#define RADAR_PARAM_MOVE_STATUS "move_status"
|
|
#define RADAR_PARAM_MOVE_COUNT "move_count"
|
|
#define RADAR_PARAM_MOVE_THRESHOLD "move_threshold"
|
|
#define RADAR_PARAM_FILTER_WINDOW "filter_window"
|
|
#define RADAR_PARAM_FILTER_COUNT "filter_count"
|
|
#define RADAR_PARAM_THRESHOLD_CALIBRATE "threshold_calibrate"
|
|
#define RADAR_PARAM_THRESHOLD_CALIBRATE_TIMEOUT "threshold_calibrate_timeout"
|
|
static led_strip_handle_t led_strip;
|
|
typedef struct {
|
|
bool threshold_calibrate; /**< Self-calibration acquisition, the most suitable threshold, calibration is to ensure that no one is in the room */
|
|
uint8_t threshold_calibrate_timeout; /**< Calibration timeout, the unit is second */
|
|
float someone_timeout; /**< The unit is second, how long no one moves in the room is marked as no one */
|
|
float move_threshold; /**< Use to determine whether someone is moving */
|
|
uint8_t filter_window; /**< window without filtering outliers */
|
|
uint8_t filter_count; /**< Detect multiple times within the outlier window greater than move_threshold to mark as someone moving */
|
|
} radar_detect_config_t;
|
|
|
|
static const char *TAG = "app_main";
|
|
static float g_someone_threshold = 0.002;
|
|
static nvs_handle_t g_nvs_handle = 0;
|
|
static int32_t g_auto_calibrate_timerleft = 0;
|
|
static TimerHandle_t g_auto_calibrate_timerhandle = NULL;
|
|
static esp_rmaker_device_t *radar_device = NULL;
|
|
static radar_detect_config_t g_detect_config = {
|
|
.someone_timeout = 3 * 60,
|
|
.move_threshold = 0.002,
|
|
.filter_window = 5,
|
|
.filter_count = 2,
|
|
.threshold_calibrate_timeout = 60,
|
|
};
|
|
|
|
static esp_err_t ping_router_start(uint32_t interval_ms)
|
|
{
|
|
static esp_ping_handle_t ping_handle = NULL;
|
|
esp_ping_config_t config = ESP_PING_DEFAULT_CONFIG();
|
|
config.count = 0;
|
|
config.timeout_ms = 1000;
|
|
config.data_size = 1;
|
|
config.interval_ms = interval_ms;
|
|
|
|
/**
|
|
* @brief Get the Router IP information from the esp-netif
|
|
*/
|
|
esp_netif_ip_info_t local_ip;
|
|
esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &local_ip);
|
|
ESP_LOGI(TAG, "Ping: got ip:" IPSTR ", gw: " IPSTR, IP2STR(&local_ip.ip), IP2STR(&local_ip.gw));
|
|
config.target_addr.u_addr.ip4.addr = ip4_addr_get_u32(&local_ip.gw);
|
|
config.target_addr.type = ESP_IPADDR_TYPE_V4;
|
|
|
|
// esp_ping_get_target(PING_TARGET_IP_ADDRESS, &config.target_addr, sizeof(ip_addr_t));
|
|
esp_ping_callbacks_t cbs = { 0 };
|
|
esp_ping_new_session(&config, &cbs, &ping_handle);
|
|
esp_ping_start(ping_handle);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static void radar_cb(void *ctx, const wifi_radar_info_t *info)
|
|
{
|
|
bool someone_status = false;
|
|
bool move_status = false;
|
|
|
|
/**
|
|
* @brief Filtering outliers is more accurate using detection,
|
|
* but it takes more time, lower sensitive to the environment
|
|
*
|
|
* @note Current algorithm limitations:
|
|
* 1. Calibration is required to detect whether there are people in the room;
|
|
* 2. No calibration is required to detect movement, but the sensitivity is higher after calibration
|
|
*/
|
|
static uint32_t s_buff_count = 0;
|
|
static float s_buff_jitter[RADAR_DETECT_BUFF_MAX_SIZE] = {0};
|
|
uint32_t buff_max_size = g_detect_config.filter_window;
|
|
uint32_t buff_outliers_num = g_detect_config.filter_count;
|
|
|
|
s_buff_jitter[s_buff_count % buff_max_size] = info->waveform_jitter;
|
|
|
|
if (++s_buff_count < buff_max_size) {
|
|
return;
|
|
}
|
|
|
|
for (int i = 0, move_count = 0; i < buff_max_size; i++) {
|
|
if (s_buff_jitter[i] > g_detect_config.move_threshold) {
|
|
move_count++;
|
|
}
|
|
|
|
if (move_count >= buff_outliers_num) {
|
|
move_status = true;
|
|
}
|
|
}
|
|
|
|
someone_status = (info->waveform_jitter > g_someone_threshold) ? true : false;
|
|
static uint32_t s_count = 0;
|
|
|
|
if (!s_count++) {
|
|
ESP_LOGI(TAG, "================ RADAR RECV ================");
|
|
ESP_LOGI(TAG, "type,sequence,timestamp,waveform_wander,someone_threshold,someone_status,waveform_jitter,move_threshold,move_status\n");
|
|
}
|
|
|
|
ESP_LOGI("RADAR_DADA", "RADAR_DADA,%d,%u,%.6f,%.6f,%d,%.6f,%.6f,%d",
|
|
s_count, esp_log_timestamp(),
|
|
info->waveform_wander, g_someone_threshold, someone_status,
|
|
info->waveform_jitter, g_detect_config.move_threshold, move_status);
|
|
|
|
/* Calibrate the environment, LED will flash yellow */
|
|
if (g_detect_config.threshold_calibrate) {
|
|
static bool led_status = false;
|
|
|
|
if (led_status) {
|
|
led_strip_set_pixel(led_strip, 0, 0, 0);
|
|
} else {
|
|
led_strip_set_pixel(led_strip, 0, 255, 255, 0);
|
|
}
|
|
led_strip_refresh(led_strip);
|
|
led_status = !led_status;
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @brief Use LED and LOG to display the detection results
|
|
* 1. Someone moves in the room, LED will flash green
|
|
* 2. No one moves in the room, LED will flash white
|
|
* 3. No one in the room, LED will turn off
|
|
*/
|
|
static uint32_t s_last_move_time = 0;
|
|
static bool s_last_move_status = false;
|
|
|
|
if (esp_log_timestamp() - s_last_move_time < g_detect_config.someone_timeout * 1000) {
|
|
someone_status = true;
|
|
} else {
|
|
someone_status = false;
|
|
}
|
|
|
|
if (move_status) {
|
|
if (move_status != s_last_move_status) {
|
|
led_strip_set_pixel(led_strip, 0, 0, 255, 0);
|
|
ESP_LOGI(TAG, "someone moves in the room");
|
|
}
|
|
|
|
s_last_move_time = esp_log_timestamp();
|
|
} else if (move_status != s_last_move_status) {
|
|
ESP_LOGI(TAG, "No one moves in the room");
|
|
} else if (esp_log_timestamp() - s_last_move_time > 3 * 1000) {
|
|
if (someone_status) {
|
|
led_strip_set_pixel(led_strip, 0, 255, 255, 255);
|
|
} else {
|
|
led_strip_set_pixel(led_strip, 0, 0, 0, 0);
|
|
}
|
|
}
|
|
led_strip_refresh(led_strip);
|
|
s_last_move_status = move_status;
|
|
|
|
/**
|
|
* @brief Report the room status to the cloud every 10 seconds or when the room status changes
|
|
*/
|
|
if (!esp_rmaker_time_check()) {
|
|
return;
|
|
}
|
|
|
|
static bool s_report_someone_status = false;
|
|
static bool s_report_move_status = false;
|
|
static uint32_t s_report_move_count = 0;
|
|
static uint32_t s_report_move_timestamp = 0;
|
|
s_report_move_count = move_status ? s_report_move_count + 1 : s_report_move_count;
|
|
|
|
if (s_report_someone_status != someone_status && !someone_status) {
|
|
esp_rmaker_param_t *someone_status_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_SOMEONE_STATUS);
|
|
esp_rmaker_param_update_and_report(someone_status_param, esp_rmaker_bool(someone_status));
|
|
s_report_someone_status = someone_status;
|
|
}
|
|
|
|
if (move_status != s_report_move_status
|
|
/* Reduce the number of times to report data and reduce server pressure */
|
|
|| (move_status && esp_log_timestamp() - s_report_move_timestamp > 10 * 1000)) {
|
|
esp_rmaker_param_t *someone_status_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_SOMEONE_STATUS);
|
|
esp_rmaker_param_update(someone_status_param, esp_rmaker_bool(someone_status));
|
|
esp_rmaker_param_t *move_status_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_MOVE_STATUS);
|
|
esp_rmaker_param_update(move_status_param, esp_rmaker_bool(move_status | (s_report_move_count > 0)));
|
|
esp_rmaker_param_t *move_count_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_MOVE_COUNT);
|
|
esp_rmaker_param_update_and_report(move_count_param, esp_rmaker_int(s_report_move_count));
|
|
|
|
if (!s_report_move_status || !s_report_move_count) {
|
|
s_report_move_status = move_status;
|
|
}
|
|
|
|
s_report_move_count = 0;
|
|
s_report_move_timestamp = esp_log_timestamp();
|
|
}
|
|
}
|
|
|
|
static esp_err_t radar_start()
|
|
{
|
|
esp_radar_config_t radar_config = ESP_RADAR_CONFIG_DEFAULT();
|
|
#if CONFIG_IDF_TARGET_ESP32C5 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32C61
|
|
// radar_config.csi_config.acquire_csi_lltf = true;
|
|
// radar_config.csi_config.htltf_en = true;
|
|
#else
|
|
// radar_config.csi_config.lltf_en = true;
|
|
// radar_config.csi_config.htltf_en = true;
|
|
|
|
#endif
|
|
radar_config.dec_config.wifi_radar_cb = radar_cb;
|
|
|
|
wifi_ap_record_t ap_info = {0x0};
|
|
esp_wifi_sta_get_ap_info(&ap_info);
|
|
memcpy(radar_config.csi_config.filter_mac, ap_info.bssid, sizeof(ap_info.bssid));
|
|
ESP_ERROR_CHECK(esp_radar_csi_init(&radar_config.csi_config));
|
|
ESP_ERROR_CHECK(esp_radar_dec_init(&radar_config.dec_config));
|
|
|
|
esp_radar_start();
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
static void auto_calibrate_timercb(TimerHandle_t timer)
|
|
{
|
|
g_auto_calibrate_timerleft -= AUTO_CALIBRATE_RAPORT_INTERVAL;
|
|
|
|
if (g_auto_calibrate_timerleft < AUTO_CALIBRATE_RAPORT_INTERVAL) {
|
|
g_auto_calibrate_timerleft = g_detect_config.threshold_calibrate_timeout;
|
|
g_detect_config.threshold_calibrate = false;
|
|
xTimerStop(g_auto_calibrate_timerhandle, portMAX_DELAY);
|
|
|
|
esp_radar_train_stop(&g_someone_threshold, &g_detect_config.move_threshold);
|
|
esp_rmaker_param_t *move_threshold_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_MOVE_THRESHOLD);
|
|
esp_rmaker_param_update(move_threshold_param, esp_rmaker_float(g_detect_config.move_threshold));
|
|
|
|
nvs_set_blob(g_nvs_handle, "detect_config", &g_detect_config, sizeof(radar_detect_config_t));
|
|
nvs_commit(g_nvs_handle);
|
|
}
|
|
|
|
esp_rmaker_param_t *param_threshold_calibrate = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_THRESHOLD_CALIBRATE);
|
|
esp_rmaker_param_update(param_threshold_calibrate, esp_rmaker_bool(g_detect_config.threshold_calibrate));
|
|
esp_rmaker_param_t *param_threshold_calibrate_timeout = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_THRESHOLD_CALIBRATE_TIMEOUT);
|
|
esp_rmaker_param_update_and_report(param_threshold_calibrate_timeout, esp_rmaker_int(g_auto_calibrate_timerleft));
|
|
}
|
|
|
|
/* Callback to handle commands received from the RainMaker cloud */
|
|
static esp_err_t write_cb(const esp_rmaker_device_t *device, const esp_rmaker_param_t *param,
|
|
const esp_rmaker_param_val_t val, void *priv_data, esp_rmaker_write_ctx_t *ctx)
|
|
{
|
|
const char *param_name = esp_rmaker_param_get_name(param);
|
|
|
|
if (strcmp(param_name, RADAR_PARAM_SOMEONE_TIMEOUT) == 0) {
|
|
g_detect_config.someone_timeout = val.val.i;
|
|
} else if (strcmp(param_name, RADAR_PARAM_MOVE_THRESHOLD) == 0) {
|
|
g_detect_config.move_threshold = val.val.f;
|
|
} else if (strcmp(param_name, RADAR_PARAM_FILTER_WINDOW) == 0) {
|
|
g_detect_config.filter_window = val.val.i;
|
|
} else if (strcmp(param_name, RADAR_PARAM_FILTER_COUNT) == 0) {
|
|
g_detect_config.filter_count = val.val.i;
|
|
} else if (strcmp(param_name, RADAR_PARAM_THRESHOLD_CALIBRATE) == 0) {
|
|
g_detect_config.threshold_calibrate = val.val.b;
|
|
|
|
if (!g_auto_calibrate_timerhandle) {
|
|
g_auto_calibrate_timerhandle = xTimerCreate("auto_calibrate", pdMS_TO_TICKS(AUTO_CALIBRATE_RAPORT_INTERVAL * 1000),
|
|
true, NULL, auto_calibrate_timercb);
|
|
}
|
|
|
|
if (g_detect_config.threshold_calibrate) {
|
|
g_auto_calibrate_timerleft = g_detect_config.threshold_calibrate_timeout;
|
|
xTimerStart(g_auto_calibrate_timerhandle, portMAX_DELAY);
|
|
esp_radar_train_start();
|
|
} else {
|
|
g_auto_calibrate_timerleft = 0;
|
|
auto_calibrate_timercb(NULL);
|
|
}
|
|
} else if (strcmp(param_name, RADAR_PARAM_THRESHOLD_CALIBRATE_TIMEOUT) == 0) {
|
|
g_detect_config.threshold_calibrate_timeout = val.val.i;
|
|
} else {
|
|
ESP_LOGE(TAG, "Unhandled parameter '%s'", param_name);
|
|
/* Silently ignoring invalid params */
|
|
return ESP_OK;
|
|
}
|
|
|
|
esp_rmaker_param_update_and_report(param, val);
|
|
nvs_set_blob(g_nvs_handle, "detect_config", &g_detect_config, sizeof(radar_detect_config_t));
|
|
nvs_commit(g_nvs_handle);
|
|
return ESP_OK;
|
|
}
|
|
esp_err_t ws2812_led_init(void)
|
|
{
|
|
led_strip_config_t strip_config = {
|
|
.strip_gpio_num = WS2812_GPIO,
|
|
.max_leds = 1,
|
|
};
|
|
|
|
led_strip_rmt_config_t rmt_config = {
|
|
.clk_src = RMT_CLK_SRC_DEFAULT, // different clock source can lead to different power consumption
|
|
.resolution_hz = 10 * 1000 * 1000, // RMT counter clock frequency: 10MHz
|
|
.flags = {
|
|
.with_dma = false, // DMA feature is available on chips like ESP32-S3/P4
|
|
}
|
|
};
|
|
ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip));
|
|
/* Set all LED off to clear all pixels */
|
|
led_strip_clear(led_strip);
|
|
return ESP_OK;
|
|
}
|
|
void app_main()
|
|
{
|
|
/* Initialize Application specific hardware drivers and set initial state */
|
|
ws2812_led_init();
|
|
button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LOW);
|
|
app_reset_button_register(btn_handle, BUTTON_WIFI_RESET_TIMEOUT, BUTTON_FACTORY_RESET_TIMEOUT);
|
|
|
|
/* Initialize NVS. */
|
|
esp_err_t err = nvs_flash_init();
|
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
|
ESP_ERROR_CHECK(nvs_flash_erase());
|
|
err = nvs_flash_init();
|
|
}
|
|
ESP_ERROR_CHECK(err);
|
|
nvs_open("wifi_radar", NVS_READWRITE, &g_nvs_handle);
|
|
size_t detect_config_size = sizeof(radar_detect_config_t);
|
|
nvs_get_blob(g_nvs_handle, "detect_config", &g_detect_config, &detect_config_size);
|
|
|
|
/* Reduced output log */
|
|
// esp_log_level_set("esp_radar", ESP_LOG_WARN);
|
|
esp_log_level_set("RADAR_DADA", ESP_LOG_WARN);
|
|
|
|
/* Initialize Wi-Fi. Note that, this should be called before esp_rmaker_node_init() */
|
|
app_wifi_init();
|
|
|
|
/* Initialize the ESP RainMaker Agent */
|
|
esp_rmaker_config_t rainmaker_cfg = {
|
|
.enable_time_sync = true,
|
|
};
|
|
esp_rmaker_node_t *node = esp_rmaker_node_init(&rainmaker_cfg, "ESP Wi-Fi CSI Device", "Wi-Fi Radar");
|
|
if (!node) {
|
|
ESP_LOGE(TAG, "Could not initialise node. Aborting!!!");
|
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
|
abort();
|
|
}
|
|
|
|
/* Create a device and add the relevant parameters to it */
|
|
radar_device = esp_rmaker_device_create("Sensor Light", ESP_RMAKER_DEVICE_LIGHTBULB, NULL);
|
|
ESP_ERROR_CHECK(esp_rmaker_device_add_cb(radar_device, write_cb, NULL));
|
|
|
|
typedef struct {
|
|
const char *param_name;
|
|
uint8_t properties;
|
|
const char *ui_type;
|
|
esp_rmaker_param_val_t val;
|
|
esp_rmaker_param_val_t min;
|
|
esp_rmaker_param_val_t max;
|
|
esp_rmaker_param_val_t step;
|
|
} radar_param_t;
|
|
esp_rmaker_param_val_t invalid_val = {.type = RMAKER_VAL_TYPE_INVALID};
|
|
radar_param_t radar_param_list[] = {
|
|
{RADAR_PARAM_THRESHOLD_CALIBRATE, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TOGGLE, esp_rmaker_bool(g_detect_config.threshold_calibrate), invalid_val, invalid_val, invalid_val},
|
|
{RADAR_PARAM_THRESHOLD_CALIBRATE_TIMEOUT, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TEXT, esp_rmaker_int(g_detect_config.threshold_calibrate_timeout), esp_rmaker_int(10), esp_rmaker_int(3600), esp_rmaker_int(10)},
|
|
{RADAR_PARAM_MOVE_THRESHOLD, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TEXT, esp_rmaker_float(g_detect_config.move_threshold), esp_rmaker_float(0.01), esp_rmaker_float(0.1), esp_rmaker_float(0.01)},
|
|
{RADAR_PARAM_MOVE_STATUS, PROP_FLAG_READ, ESP_RMAKER_UI_TEXT, esp_rmaker_bool(false), invalid_val, invalid_val, invalid_val},
|
|
{RADAR_PARAM_MOVE_COUNT, PROP_FLAG_READ | PROP_FLAG_TIME_SERIES, ESP_RMAKER_UI_TEXT, esp_rmaker_int(0), esp_rmaker_int(0), esp_rmaker_int(100), esp_rmaker_int(1)},
|
|
{RADAR_PARAM_SOMEONE_STATUS, PROP_FLAG_READ, ESP_RMAKER_UI_TEXT, esp_rmaker_bool(false), invalid_val, invalid_val, invalid_val},
|
|
{RADAR_PARAM_SOMEONE_TIMEOUT, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TEXT, esp_rmaker_int(g_detect_config.someone_timeout), esp_rmaker_int(10), esp_rmaker_int(3600), esp_rmaker_int(10)},
|
|
{RADAR_PARAM_FILTER_WINDOW, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TEXT, esp_rmaker_int(g_detect_config.filter_window), esp_rmaker_int(1), esp_rmaker_int(16), esp_rmaker_int(1)},
|
|
{RADAR_PARAM_FILTER_COUNT, PROP_FLAG_READ | PROP_FLAG_WRITE, ESP_RMAKER_UI_TEXT, esp_rmaker_int(g_detect_config.filter_count), esp_rmaker_int(1), esp_rmaker_int(16), esp_rmaker_int(1)},
|
|
};
|
|
|
|
for (int i = 0; i < sizeof(radar_param_list) / sizeof(radar_param_list[0]); ++i) {
|
|
char radar_param_type[64] = "esp.param.";
|
|
strcat(radar_param_type, radar_param_list[i].param_name);
|
|
esp_rmaker_param_t *param = esp_rmaker_param_create(radar_param_list[i].param_name, radar_param_type,
|
|
radar_param_list[i].val, radar_param_list[i].properties);
|
|
|
|
if (radar_param_list[i].ui_type) {
|
|
esp_rmaker_param_add_ui_type(param, radar_param_list[i].ui_type);
|
|
}
|
|
|
|
if (radar_param_list[i].min.type != RMAKER_VAL_TYPE_INVALID) {
|
|
esp_rmaker_param_add_bounds(param, radar_param_list[i].min, radar_param_list[i].max, radar_param_list[i].step);
|
|
}
|
|
|
|
ESP_ERROR_CHECK(esp_rmaker_device_add_param(radar_device, param));
|
|
}
|
|
|
|
esp_rmaker_param_t *move_count_param = esp_rmaker_device_get_param_by_name(radar_device, RADAR_PARAM_MOVE_COUNT);
|
|
esp_rmaker_device_assign_primary_param(radar_device, move_count_param);
|
|
ESP_ERROR_CHECK(esp_rmaker_node_add_device(node, radar_device));
|
|
|
|
/* Enable OTA */
|
|
ESP_ERROR_CHECK(esp_rmaker_ota_enable_default());
|
|
|
|
/* Enable timezone service which will be require for setting appropriate timezone
|
|
* from the phone apps for scheduling to work correctly.
|
|
* For more information on the various ways of setting timezone, please check
|
|
* https://rainmaker.espressif.com/docs/time-service.html.
|
|
*/
|
|
esp_rmaker_timezone_service_enable();
|
|
|
|
/* Enable scheduling. */
|
|
esp_rmaker_schedule_enable();
|
|
|
|
/* Enable Scenes */
|
|
esp_rmaker_scenes_enable();
|
|
|
|
/* Start the ESP RainMaker Agent */
|
|
esp_rmaker_start();
|
|
|
|
/* Start the Wi-Fi./
|
|
* If the node is provisioned, it will start connection attempts,
|
|
* else, it will start Wi-Fi provisioning. The function will return
|
|
* after a connection has been successfully established
|
|
*/
|
|
err = app_wifi_start(POP_TYPE_NONE);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
|
vTaskDelay(pdMS_TO_TICKS(5000));
|
|
abort();
|
|
}
|
|
|
|
/**
|
|
* @brief Enable Wi-Fi Radar Detection
|
|
*/
|
|
radar_start();
|
|
ping_router_start(RADAR_PING_DATA_INTERVAL);
|
|
}
|