mirror of
https://github.com/espressif/esp-rainmaker.git
synced 2026-01-16 01:15:38 +00:00
220 lines
8.3 KiB
C++
220 lines
8.3 KiB
C++
/*
|
|
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.
|
|
*/
|
|
|
|
#include <esp_err.h>
|
|
#include <esp_log.h>
|
|
#include <nvs_flash.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 <app_insights.h>
|
|
#include <app_reset.h>
|
|
#include <esp_rmaker_console.h>
|
|
|
|
#include "app_priv.h"
|
|
#include <app_matter.h>
|
|
#include "app_matter_light.h"
|
|
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
|
#include <platform/ThreadStackManager.h>
|
|
#include <platform/ESP32/OpenthreadLauncher.h>
|
|
#endif
|
|
#ifndef CONFIG_EXAMPLE_USE_RAINMAKER_FABRIC
|
|
#include <app_network.h>
|
|
#include <esp_rmaker_user_mapping.h>
|
|
#include <network_provisioning/manager.h>
|
|
#include <matter_commissioning_window_management.h>
|
|
#if CONFIG_DYNAMIC_PASSCODE_COMMISSIONABLE_DATA_PROVIDER
|
|
#include <esp_matter_providers.h>
|
|
#include <dynamic_commissionable_data_provider.h>
|
|
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
|
|
#include <setup_payload/OnboardingCodesUtil.h>
|
|
dynamic_commissionable_data_provider g_dynamic_passcode_provider;
|
|
#endif
|
|
#endif
|
|
|
|
static const char *TAG = "app_main";
|
|
|
|
static app_driver_handle_t light_handle;
|
|
|
|
bool rmaker_init_done = false; // used with extern in `app_matter.c`
|
|
|
|
/* Callback to handle commands received from the RainMaker cloud */
|
|
static esp_err_t bulk_write_cb(const esp_rmaker_device_t *device, const esp_rmaker_param_write_req_t write_req[],
|
|
uint8_t count, void *priv_data, esp_rmaker_write_ctx_t *ctx)
|
|
{
|
|
if (ctx) {
|
|
ESP_LOGI(TAG, "Received write request via : %s", esp_rmaker_device_cb_src_to_str(ctx->src));
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Light received %d params in write", count);
|
|
for (int i = 0; i < count; i++) {
|
|
const esp_rmaker_param_t *param = write_req[i].param;
|
|
esp_rmaker_param_val_t val = write_req[i].val;
|
|
const char *param_name = esp_rmaker_param_get_name(param);
|
|
|
|
if (strcmp(param_name, ESP_RMAKER_DEF_POWER_NAME) == 0) {
|
|
app_driver_light_set_power(light_handle, val.val.b);
|
|
app_matter_report_power(val.val.b);
|
|
} else if (strcmp(param_name, ESP_RMAKER_DEF_HUE_NAME) == 0) {
|
|
app_driver_light_set_hue(light_handle, val.val.i);
|
|
app_matter_report_hue(val.val.i);
|
|
} else if (strcmp(param_name, ESP_RMAKER_DEF_SATURATION_NAME) == 0) {
|
|
app_driver_light_set_saturation(light_handle, val.val.i);
|
|
app_matter_report_saturation(val.val.i);
|
|
} else if (strcmp(param_name, ESP_RMAKER_DEF_CCT_NAME) == 0) {
|
|
app_driver_light_set_temperature(light_handle, val.val.i);
|
|
app_matter_report_temperature(val.val.i);
|
|
} else if (strcmp(param_name, ESP_RMAKER_DEF_BRIGHTNESS_NAME) == 0) {
|
|
app_driver_light_set_brightness(light_handle, val.val.i);
|
|
app_matter_report_brightness(val.val.i);
|
|
}
|
|
esp_rmaker_param_update(param, val);
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
|
|
extern "C" void app_main()
|
|
{
|
|
/* 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 );
|
|
|
|
/* Initialize drivers for light and button */
|
|
light_handle = app_driver_light_init();
|
|
app_driver_handle_t button_handle = app_driver_button_init(light_handle);
|
|
app_reset_button_register(button_handle);
|
|
|
|
/* Initialize Matter */
|
|
app_matter_init(app_attribute_update_cb,app_identification_cb);
|
|
#ifdef CONFIG_EXAMPLE_USE_RAINMAKER_FABRIC
|
|
app_matter_rmaker_init();
|
|
#else
|
|
app_network_init();
|
|
#endif
|
|
|
|
/* Create Data Model for esp-matter */
|
|
app_matter_light_create(light_handle);
|
|
|
|
#if CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
|
esp_openthread_platform_config_t ot_config = {
|
|
.radio_config = ESP_OPENTHREAD_DEFAULT_RADIO_CONFIG(),
|
|
.host_config = ESP_OPENTHREAD_DEFAULT_HOST_CONFIG(),
|
|
.port_config = ESP_OPENTHREAD_DEFAULT_PORT_CONFIG(),
|
|
};
|
|
set_openthread_platform_config(&ot_config);
|
|
// This will not really initiaize Thread stack as the thread stack has been initialzed in app_network.
|
|
// We call this function to pass the OpenThread instance to GenericThreadStackManagerImpl_OpenThread
|
|
// so that it can be used for SRP service registration and network commissioning driver.
|
|
chip::DeviceLayer::ThreadStackMgr().InitThreadStack();
|
|
#endif
|
|
|
|
/* Starting driver with default values */
|
|
app_driver_light_set_defaults();
|
|
|
|
#ifdef CONFIG_EXAMPLE_USE_RAINMAKER_FABRIC
|
|
/* Matter start */
|
|
app_matter_start(app_event_cb);
|
|
#endif
|
|
|
|
/* Create Data Model for esp-matter */
|
|
/* Initialize the ESP RainMaker Agent.
|
|
* Create Lightbulb device and its parameters.
|
|
*/
|
|
esp_rmaker_config_t rainmaker_cfg = {
|
|
.enable_time_sync = false,
|
|
};
|
|
esp_rmaker_node_t *node = esp_rmaker_node_init(&rainmaker_cfg, "ESP RainMaker Device", "Lightbulb");
|
|
if (!node) {
|
|
ESP_LOGE(TAG, "Could not initialise node.");
|
|
vTaskDelay(5000 / portTICK_PERIOD_MS);
|
|
abort();
|
|
}
|
|
|
|
esp_rmaker_device_t *light_device = esp_rmaker_lightbulb_device_create(LIGHT_DEVICE_NAME, NULL, DEFAULT_POWER);
|
|
esp_rmaker_device_add_bulk_cb(light_device, bulk_write_cb, NULL);
|
|
|
|
esp_rmaker_device_add_param(light_device, esp_rmaker_brightness_param_create(ESP_RMAKER_DEF_BRIGHTNESS_NAME, DEFAULT_BRIGHTNESS));
|
|
esp_rmaker_device_add_param(light_device, esp_rmaker_saturation_param_create(ESP_RMAKER_DEF_SATURATION_NAME, DEFAULT_SATURATION));
|
|
esp_rmaker_device_add_param(light_device, esp_rmaker_hue_param_create(ESP_RMAKER_DEF_HUE_NAME, DEFAULT_HUE));
|
|
esp_rmaker_device_add_param(light_device, esp_rmaker_cct_param_create(ESP_RMAKER_DEF_CCT_NAME, DEFAULT_TEMPERATURE));
|
|
|
|
esp_rmaker_node_add_device(node, light_device);
|
|
|
|
/* Enable OTA */
|
|
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();
|
|
|
|
/* Enable Insights. Requires CONFIG_ESP_INSIGHTS_ENABLED=y */
|
|
app_insights_enable();
|
|
|
|
/* Enable factory service */
|
|
esp_rmaker_system_serv_config_t servconfig = {
|
|
.flags = SYSTEM_SERV_FLAGS_ALL,
|
|
.reboot_seconds = 2,
|
|
.reset_reboot_seconds = 2,
|
|
};
|
|
esp_rmaker_system_service_enable(&servconfig);
|
|
|
|
#ifdef CONFIG_EXAMPLE_USE_RAINMAKER_FABRIC
|
|
/* Pre start */
|
|
ESP_ERROR_CHECK(app_matter_rmaker_start());
|
|
#else
|
|
err = app_network_set_custom_mfg_data(MGF_DATA_DEVICE_TYPE_LIGHT, MFG_DATA_DEVICE_SUBTYPE_LIGHT);
|
|
|
|
err = app_network_start(POP_TYPE_MAC);
|
|
if (err != ESP_OK) {
|
|
ESP_LOGE(TAG, "Could not start Wifi. Aborting!!!");
|
|
abort();
|
|
}
|
|
matter_commissioning_window_management_enable();
|
|
#if CONFIG_DYNAMIC_PASSCODE_COMMISSIONABLE_DATA_PROVIDER
|
|
/* This should be called before esp_matter::start() */
|
|
esp_matter::set_custom_commissionable_data_provider(&g_dynamic_passcode_provider);
|
|
#endif
|
|
/* Matter start */
|
|
app_matter_start(app_event_cb);
|
|
|
|
bool is_network_provisioned = false;
|
|
#ifdef CONFIG_ESP_RMAKER_NETWORK_OVER_WIFI
|
|
// If Wi-Fi is provisioned and RainMaker user node mapping is done, deinitialize the BLE.
|
|
network_prov_mgr_is_wifi_provisioned(&is_network_provisioned);
|
|
#else
|
|
network_prov_mgr_is_thread_provisioned(&is_network_provisioned);
|
|
#endif
|
|
if (is_network_provisioned && esp_rmaker_user_node_mapping_get_state() == ESP_RMAKER_USER_MAPPING_DONE) {
|
|
chip::DeviceLayer::PlatformMgr().ScheduleWork([](intptr_t) { chip::DeviceLayer::Internal::BLEMgr().Shutdown(); });
|
|
}
|
|
#endif
|
|
|
|
rmaker_init_done = true;
|
|
|
|
app_matter_enable_matter_console();
|
|
|
|
// RainMaker start is deferred after Matter commissioning is complete
|
|
// and BLE memory is reclaimed, so that MQTT connect doesnt fail.
|
|
}
|