mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 11:03:05 +00:00
examples: Remove rainmaker_light
This commit is contained in:
@@ -67,12 +67,6 @@ variables:
|
||||
- idf.py build
|
||||
- idf.py set-target esp32c3
|
||||
- idf.py build
|
||||
- cd $REPOS_PATH
|
||||
- git clone --recursive --single-branch -b master --reference-if-able /local_references/github/ https://github.com/espressif/esp-rainmaker.git
|
||||
- export ESP_RMAKER_PATH=$PWD/esp-rainmaker
|
||||
- cd $ESP_MATTER_PATH/examples/rainmaker_light
|
||||
- idf.py set-target esp32
|
||||
- idf.py build
|
||||
|
||||
.build_external_platform_example: &build_external_platform_example
|
||||
- rm -rf $ESP_MATTER_PATH/../platform
|
||||
|
||||
@@ -66,7 +66,6 @@ This should be done each time a new terminal is opened
|
||||
|
||||
- :project_file:`Light <examples/light/README.md>`
|
||||
- :project_file:`Light Switch <examples/light_switch/README.md>`
|
||||
- :project_file:`RainMaker Light <examples/rainmaker_light/README.md>`
|
||||
- :project_file:`Zap Light <examples/zap_light/README.md>`
|
||||
- :project_file:`Zigbee Bridge <examples/zigbee_bridge/README.md>`
|
||||
- :project_file:`BLE Mesh Bridge <examples/blemesh_bridge/README.md>`
|
||||
@@ -171,7 +170,6 @@ for it to work. Check the "Post Commissioning Setup" section in examples for mor
|
||||
|
||||
- :project_file:`Light <examples/light/README.md>`
|
||||
- :project_file:`Light Switch <examples/light_switch/README.md>`
|
||||
- :project_file:`RainMaker Light <examples/rainmaker_light/README.md>`
|
||||
- :project_file:`Zap Light <examples/zap_light/README.md>`
|
||||
- :project_file:`Zigbee Bridge <examples/zigbee_bridge/README.md>`
|
||||
- :project_file:`BLE Mesh Bridge <examples/blemesh_bridge/README.md>`
|
||||
|
||||
@@ -144,7 +144,6 @@ The LED on my devkit is not working:
|
||||
|
||||
- :project_file:`Light <examples/light/README.md>`
|
||||
- :project_file:`Light Switch <examples/light_switch/README.md>`
|
||||
- :project_file:`RainMaker Light <examples/rainmaker_light/README.md>`
|
||||
- :project_file:`Zap Light <examples/zap_light/README.md>`
|
||||
- :project_file:`Zigbee Bridge <examples/zigbee_bridge/README.md>`
|
||||
- :project_file:`BLE Mesh Bridge <examples/blemesh_bridge/README.md>`
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# The following lines of boilerplate have to be in your project's
|
||||
# CMakeLists in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
if(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||
message(FATAL_ERROR "Please set ESP_MATTER_PATH to the path of esp-matter repo")
|
||||
endif(NOT DEFINED ENV{ESP_MATTER_PATH})
|
||||
|
||||
if(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||
if("${IDF_TARGET}" STREQUAL "esp32" OR "${IDF_TARGET}" STREQUAL "")
|
||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32_devkit_c)
|
||||
elseif("${IDF_TARGET}" STREQUAL "esp32c3")
|
||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32c3_devkit_m)
|
||||
elseif("${IDF_TARGET}" STREQUAL "esp32s3")
|
||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32s3_devkit_c)
|
||||
else()
|
||||
message(FATAL_ERROR "Unsupported IDF_TARGET")
|
||||
endif()
|
||||
endif(NOT DEFINED ENV{ESP_MATTER_DEVICE_PATH})
|
||||
|
||||
set(ESP_MATTER_PATH $ENV{ESP_MATTER_PATH})
|
||||
set(MATTER_SDK_PATH ${ESP_MATTER_PATH}/connectedhomeip/connectedhomeip)
|
||||
set(ZAP_GENERATED_PATH ${CMAKE_CURRENT_LIST_DIR}/main/zap-generated)
|
||||
|
||||
if(NOT DEFINED ENV{ESP_RMAKER_PATH})
|
||||
message(FATAL_ERROR "Please set ESP_RMAKER_PATH to the path of esp-rainmaker repo")
|
||||
endif(NOT DEFINED ENV{ESP_RMAKER_PATH})
|
||||
|
||||
# This should be done before using the IDF_TARGET variable.
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
include($ENV{ESP_MATTER_DEVICE_PATH}/esp_matter_device.cmake)
|
||||
|
||||
idf_build_set_property(RAINMAKER_ENABLED 1)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
"../common"
|
||||
"${IDF_PATH}/examples/common_components"
|
||||
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||
"${ESP_MATTER_PATH}/components"
|
||||
"${ESP_MATTER_PATH}/device_hal/device"
|
||||
"$ENV{ESP_RMAKER_PATH}/components"
|
||||
${extra_components_dirs_append})
|
||||
|
||||
project(rainmaker_light)
|
||||
|
||||
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++14;-Os;-DLWIP_IPV6_SCOPES=0;-DCHIP_HAVE_CONFIG_H" APPEND)
|
||||
idf_build_set_property(C_COMPILE_OPTIONS "-Os;-DLWIP_IPV6_SCOPES=0" APPEND)
|
||||
# For RISCV chips, project_include.cmake sets -Wno-format, but does not clear various
|
||||
# flags that depend on -Wformat
|
||||
idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
|
||||
@@ -1,142 +1,3 @@
|
||||
# RainMaker Light
|
||||
|
||||
This example creates a Color Temperature Light device using the ESP
|
||||
Matter data model.
|
||||
|
||||
It also initializes [ESP RainMaker](https://rainmaker.espressif.com/) which enables Device Management and
|
||||
OTA using the RainMaker cloud. If user node association is done, it also
|
||||
enables Remote Control through RainMaker.
|
||||
|
||||
See the [docs](https://docs.espressif.com/projects/esp-matter/en/latest/esp32/developing.html) for more information about building and flashing the firmware.
|
||||
|
||||
## 1. Additional Environment Setup
|
||||
|
||||
### 1.1 Getting the Repositories
|
||||
|
||||
```
|
||||
git clone --recursive https://github.com/espressif/esp-rainmaker.git
|
||||
```
|
||||
|
||||
Setup the RainMaker CLI from here: https://rainmaker.espressif.com/docs/cli-setup.html
|
||||
|
||||
### 1.2 Configuring the Environment
|
||||
|
||||
```
|
||||
export ESP_RMAKER_PATH=/path/to/esp-rainmaker
|
||||
```
|
||||
|
||||
### 1.3 RainMaker Claiming
|
||||
|
||||
If self-claiming is not enabled/supported, this need to be done before
|
||||
flashing the firmware.
|
||||
|
||||
RainMaker CLI:
|
||||
|
||||
```
|
||||
cd $ESP_RMAKER_PATH/cli
|
||||
rainmaker.py claim --addr 0x3E0000 $ESPPORT
|
||||
```
|
||||
|
||||
## 2. Post Commissioning Setup
|
||||
|
||||
### 2.1 RainMaker User-Node Association
|
||||
|
||||
This needs to be done after commissioning.
|
||||
|
||||
Check if the device already has user node association done, using the
|
||||
custom RainMaker cluster (cluster_id: 0x131bfc00):
|
||||
|
||||
```
|
||||
chip-tool any read-by-id 0x131bfc00 0x0 0x7283 0x0
|
||||
```
|
||||
|
||||
- If the above custom status attribute (attribute_id: 0x0) returns
|
||||
true, the association has already been done.
|
||||
- If the attribute returns false, the association has not been done.
|
||||
And the below custom configuration command (command_id: 0x0) can be
|
||||
used to do the association.
|
||||
|
||||
Get the RainMaker node id (attribute_id: 0x1):
|
||||
|
||||
```
|
||||
chip-tool any read-by-id 0x131bfc00 0x1 0x7283 0x0
|
||||
```
|
||||
|
||||
RainMaker CLI:
|
||||
|
||||
Trigger user-node association using the above rainmaker-node-id: This
|
||||
will print the user-id and secret-key (do not close this):
|
||||
|
||||
```
|
||||
rainmaker.py test --addnode <rainmaker-node-id>
|
||||
|
||||
>> add-user <user-id> <secret-key>
|
||||
```
|
||||
|
||||
Prepare the command payload using the above details:
|
||||
|
||||
```
|
||||
payload: <user-id>::<secret-key>
|
||||
```
|
||||
|
||||
Now use the payload to run the RainMaker configuration command from
|
||||
chip-tool:
|
||||
|
||||
```
|
||||
chip-tool any command-by-id 0x131bfc00 0x0 '"<user-id>::<secret-key>"' 0x7283 0x0
|
||||
```
|
||||
|
||||
The device/node should now be associated with the user.
|
||||
|
||||
### 2.2 Device console
|
||||
|
||||
RainMaker specific console commands:
|
||||
|
||||
- User Node Association:
|
||||
|
||||
```
|
||||
matter esp rainmaker add-user <user-id> <secret-key>
|
||||
```
|
||||
|
||||
## 3. Device Performance
|
||||
|
||||
### 3.1 Memory usage
|
||||
|
||||
The following is the Memory and Flash Usage.
|
||||
|
||||
- `Bootup` == Device just finished booting up. Device is not
|
||||
commissionined or connected to wifi yet.
|
||||
- `After Commissioning` == Device is conneted to wifi and is also
|
||||
commissioned and is rebooted.
|
||||
- device used: esp32c3_devkit_m
|
||||
- tested on:
|
||||
[bd951b8](https://github.com/espressif/esp-matter/commit/bd951b84993d9d0b5742872be4f51bb6c9ccf15e)
|
||||
(2022-05-05)
|
||||
|
||||
| | Bootup | After Commissioning |
|
||||
|:- |:-: |:-: |
|
||||
|**Free Internal Memory** |87KB |65KB |
|
||||
|
||||
**Flash Usage**: Firmware binary size: 1.52MB
|
||||
|
||||
This should give you a good idea about the amount of free memory that is
|
||||
available for you to run your application's code.
|
||||
|
||||
## A2 Appendix FAQs
|
||||
|
||||
### A2.1 User Node association is failing
|
||||
|
||||
User Node association is failing on my device:
|
||||
|
||||
- Make sure the device has been claimed.
|
||||
- If the device prints "This command has reached a limit", reboot the
|
||||
device to run the command again.
|
||||
- Read the status attribute:
|
||||
`chip-tool any read-by-id 0x131bfc00 0x0 0x7283 0x0`. If this custom
|
||||
status attribute (attribute_id: 0x0) returns true, the association
|
||||
has already been done.
|
||||
- If you are still facing issues, reproduce the issue on the default
|
||||
example for the device and then raise an [issue](https://github.com/espressif/esp-matter/issues).
|
||||
Make sure to share these:
|
||||
- The complete device logs taken over UART.
|
||||
- The esp-matter, esp-idf and esp-rainmaker branch you are using.
|
||||
Matter Light with RainMaker will be soon available in [RainMaker Examples](https://github.com/espressif/esp-rainmaker/tree/master/examples).
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
set(PRIV_REQUIRES_LIST device esp_matter esp_matter_console esp_matter_rainmaker route_hook app_qrcode app_reset
|
||||
esp_rainmaker)
|
||||
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
PRIV_REQUIRES ${PRIV_REQUIRES_LIST})
|
||||
|
||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 14)
|
||||
target_compile_options(${COMPONENT_LIB} PRIVATE "-DLWIP_IPV6_SCOPES=0" "-DCHIP_HAVE_CONFIG_H")
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
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_log.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <device.h>
|
||||
#include <esp_matter.h>
|
||||
#include <led_driver.h>
|
||||
|
||||
#include <app_reset.h>
|
||||
#include <app_priv.h>
|
||||
|
||||
using namespace esp_matter;
|
||||
|
||||
static const char *TAG = "app_driver";
|
||||
extern uint16_t light_endpoint_id;
|
||||
|
||||
/* Do any conversions/remapping for the actual value here */
|
||||
static esp_err_t app_driver_light_set_power(esp_matter_attr_val_t *val)
|
||||
{
|
||||
return led_driver_set_power(val->val.b);
|
||||
}
|
||||
|
||||
static esp_err_t app_driver_light_set_brightness(esp_matter_attr_val_t *val)
|
||||
{
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_BRIGHTNESS, STANDARD_BRIGHTNESS);
|
||||
return led_driver_set_brightness(value);
|
||||
}
|
||||
|
||||
static esp_err_t app_driver_light_set_hue(esp_matter_attr_val_t *val)
|
||||
{
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_HUE, STANDARD_HUE);
|
||||
return led_driver_set_hue(value);
|
||||
}
|
||||
|
||||
static esp_err_t app_driver_light_set_saturation(esp_matter_attr_val_t *val)
|
||||
{
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_SATURATION, STANDARD_SATURATION);
|
||||
return led_driver_set_saturation(value);
|
||||
}
|
||||
|
||||
static esp_err_t app_driver_light_set_temperature(esp_matter_attr_val_t *val)
|
||||
{
|
||||
uint32_t value = REMAP_TO_RANGE_INVERSE(val->val.u16, STANDARD_TEMPERATURE_FACTOR);
|
||||
return led_driver_set_temperature(value);
|
||||
}
|
||||
|
||||
static void app_driver_button_toggle_cb(void *arg)
|
||||
{
|
||||
ESP_LOGI(TAG, "Toggle button pressed");
|
||||
uint16_t endpoint_id = light_endpoint_id;
|
||||
uint32_t cluster_id = OnOff::Id;
|
||||
uint32_t attribute_id = OnOff::Attributes::OnOff::Id;
|
||||
|
||||
node_t *node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get(node, endpoint_id);
|
||||
cluster_t *cluster = cluster::get(endpoint, cluster_id);
|
||||
attribute_t *attribute = attribute::get(cluster, attribute_id);
|
||||
|
||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||
attribute::get_val(attribute, &val);
|
||||
val.val.b = !val.val.b;
|
||||
attribute::update(endpoint_id, cluster_id, attribute_id, &val);
|
||||
}
|
||||
|
||||
esp_err_t app_driver_attribute_update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||
esp_matter_attr_val_t *val)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
if (endpoint_id == light_endpoint_id) {
|
||||
if (cluster_id == OnOff::Id) {
|
||||
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||
err = app_driver_light_set_power(val);
|
||||
}
|
||||
} else if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
err = app_driver_light_set_brightness(val);
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
err = app_driver_light_set_hue(val);
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
err = app_driver_light_set_saturation(val);
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
err = app_driver_light_set_temperature(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t app_driver_attribute_set_defaults()
|
||||
{
|
||||
/* Get the default value (current value) from esp_matter and update the app_driver */
|
||||
esp_err_t err = ESP_OK;
|
||||
node_t *node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get_first(node);
|
||||
while (endpoint) {
|
||||
uint16_t endpoint_id = endpoint::get_id(endpoint);
|
||||
cluster_t *cluster = cluster::get_first(endpoint);
|
||||
while (cluster) {
|
||||
uint32_t cluster_id = cluster::get_id(cluster);
|
||||
attribute_t *attribute = attribute::get_first(cluster);
|
||||
while (attribute) {
|
||||
uint32_t attribute_id = attribute::get_id(attribute);
|
||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||
err |= attribute::get_val(attribute, &val);
|
||||
err |= app_driver_attribute_update(endpoint_id, cluster_id, attribute_id, &val);
|
||||
attribute = attribute::get_next(attribute);
|
||||
}
|
||||
cluster = cluster::get_next(cluster);
|
||||
}
|
||||
endpoint = endpoint::get_next(endpoint);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t app_driver_init()
|
||||
{
|
||||
ESP_LOGI(TAG, "Initialising driver");
|
||||
|
||||
/* Initialize button */
|
||||
button_config_t button_config = button_driver_get_config();
|
||||
button_handle_t handle = iot_button_create(&button_config);
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_toggle_cb);
|
||||
app_reset_button_register(handle);
|
||||
|
||||
/* Initialize led */
|
||||
led_driver_config_t led_config = led_driver_get_config();
|
||||
led_driver_init(&led_config);
|
||||
|
||||
app_driver_attribute_set_defaults();
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
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_matter.h>
|
||||
#include <esp_matter_console.h>
|
||||
#include <esp_route_hook.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
#include <app_qrcode.h>
|
||||
#include <app_rainmaker.h>
|
||||
|
||||
static const char *TAG = "app_main";
|
||||
uint16_t light_endpoint_id = 0;
|
||||
|
||||
using namespace esp_matter;
|
||||
using namespace esp_matter::attribute;
|
||||
using namespace esp_matter::endpoint;
|
||||
|
||||
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
|
||||
{
|
||||
switch (event->Type) {
|
||||
case chip::DeviceLayer::DeviceEventType::PublicEventTypes::kInterfaceIpAddressChanged:
|
||||
#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD
|
||||
chip::app::DnssdServer::Instance().StartServer();
|
||||
esp_route_hook_init(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"));
|
||||
#endif
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::PublicEventTypes::kCommissioningComplete:
|
||||
ESP_LOGI(TAG, "Commissioning complete");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t app_attribute_update_cb(callback_type_t type, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val, void *priv_data)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
if (type == PRE_UPDATE) {
|
||||
/* Driver update */
|
||||
err = app_driver_attribute_update(endpoint_id, cluster_id, attribute_id, val);
|
||||
} else if (type == POST_UPDATE) {
|
||||
/* Rainmaker update */
|
||||
err = app_rainmaker_attribute_update(endpoint_id, cluster_id, attribute_id, val);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
/* Initialize the ESP NVS layer */
|
||||
nvs_flash_init();
|
||||
|
||||
/* Create a Matter node */
|
||||
node::config_t node_config;
|
||||
node_t *node = node::create(&node_config, app_attribute_update_cb, NULL);
|
||||
|
||||
color_temperature_light::config_t light_config;
|
||||
light_config.on_off.on_off = DEFAULT_POWER;
|
||||
light_config.level_control.current_level = DEFAULT_BRIGHTNESS;
|
||||
endpoint_t *endpoint = color_temperature_light::create(node, &light_config, ENDPOINT_FLAG_NONE);
|
||||
|
||||
/* These node and endpoint handles can be used to create/add other endpoints and clusters. */
|
||||
if (!node || !endpoint) {
|
||||
ESP_LOGE(TAG, "Matter node creation failed");
|
||||
}
|
||||
|
||||
light_endpoint_id = endpoint::get_id(endpoint);
|
||||
ESP_LOGI(TAG, "Light created with endpoint_id %d", light_endpoint_id);
|
||||
|
||||
/* Add additional features to the node */
|
||||
cluster_t *cluster = cluster::get(endpoint, ColorControl::Id);
|
||||
color_control::feature::hue_saturation::config_t hue_saturation_config;
|
||||
hue_saturation_config.current_hue = DEFAULT_HUE;
|
||||
hue_saturation_config.current_saturation = DEFAULT_SATURATION;
|
||||
color_control::feature::hue_saturation::add(cluster, &hue_saturation_config);
|
||||
|
||||
/* Initialize driver */
|
||||
app_driver_init();
|
||||
|
||||
/* Initialize rainmaker */
|
||||
app_rainmaker_init();
|
||||
|
||||
/* Matter start */
|
||||
err = esp_matter::start(app_event_cb);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Matter start failed: %d", err);
|
||||
}
|
||||
app_qrcode_print();
|
||||
|
||||
/* Start rainmaker */
|
||||
app_rainmaker_start();
|
||||
|
||||
#if CONFIG_ENABLE_CHIP_SHELL
|
||||
esp_matter_console_diagnostics_register_commands();
|
||||
esp_matter_console_init();
|
||||
#endif
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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 <esp_err.h>
|
||||
#include <esp_matter.h>
|
||||
|
||||
/** Standard max values (used for remapping attributes) */
|
||||
#define STANDARD_BRIGHTNESS 100
|
||||
#define STANDARD_HUE 360
|
||||
#define STANDARD_SATURATION 100
|
||||
#define STANDARD_TEMPERATURE_FACTOR 1000000
|
||||
|
||||
/** Matter max values (used for remapping attributes) */
|
||||
#define MATTER_BRIGHTNESS 254
|
||||
#define MATTER_HUE 255
|
||||
#define MATTER_SATURATION 255
|
||||
#define MATTER_TEMPERATURE_FACTOR 1000000
|
||||
|
||||
/** Default attribute values used during initialization */
|
||||
#define DEFAULT_POWER true
|
||||
#define DEFAULT_BRIGHTNESS 64
|
||||
#define DEFAULT_HUE 128
|
||||
#define DEFAULT_SATURATION 255
|
||||
|
||||
/** Initialize the board and the drivers
|
||||
*
|
||||
* This initializes the selected board, which then initializes the respective drivers associated with it.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_driver_init(void);
|
||||
|
||||
/** Driver Update
|
||||
*
|
||||
* This API should be called to update the driver for the attribute being updated.
|
||||
* This is usually called from the common `app_attribute_update_cb()`.
|
||||
*
|
||||
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||
* @param[in] cluster_id Cluster ID of the attribute.
|
||||
* @param[in] attribute_id Attribute ID of the attribute.
|
||||
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_driver_attribute_update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||
esp_matter_attr_val_t *val);
|
||||
@@ -1,463 +0,0 @@
|
||||
/*
|
||||
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_log.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <nvs_flash.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <esp_rmaker_core.h>
|
||||
#include <esp_rmaker_ota.h>
|
||||
#include <esp_rmaker_schedule.h>
|
||||
#include <esp_rmaker_standard_devices.h>
|
||||
#include <esp_rmaker_standard_params.h>
|
||||
#include <esp_rmaker_standard_types.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
#include <app_rainmaker.h>
|
||||
#include <esp_matter.h>
|
||||
#include <esp_matter_console.h>
|
||||
#include <esp_matter_rainmaker.h>
|
||||
|
||||
using namespace esp_matter;
|
||||
|
||||
static const char *TAG = "app_rainmaker";
|
||||
extern uint16_t light_endpoint_id;
|
||||
|
||||
#define DEFAULT_LIGHT_NAME "Light"
|
||||
|
||||
static esp_rmaker_param_val_t app_rainmaker_get_rmaker_val(esp_matter_attr_val_t *val, uint32_t cluster_id,
|
||||
uint32_t attribute_id)
|
||||
{
|
||||
/* Attributes which need to be remapped */
|
||||
if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_BRIGHTNESS, STANDARD_BRIGHTNESS);
|
||||
return esp_rmaker_int(value);
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_HUE, STANDARD_HUE);
|
||||
return esp_rmaker_int(value);
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
int value = REMAP_TO_RANGE(val->val.u8, MATTER_SATURATION, STANDARD_SATURATION);
|
||||
return esp_rmaker_int(value);
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
int value = REMAP_TO_RANGE_INVERSE(val->val.u16, STANDARD_TEMPERATURE_FACTOR);
|
||||
return esp_rmaker_int(value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Attributes which don't need to be remapped */
|
||||
if (val->type == ESP_MATTER_VAL_TYPE_BOOLEAN) {
|
||||
return esp_rmaker_bool(val->val.b);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_INTEGER) {
|
||||
return esp_rmaker_int(val->val.i);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_FLOAT) {
|
||||
return esp_rmaker_float(val->val.f);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_UINT8) {
|
||||
return esp_rmaker_int(val->val.u8);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_INT16) {
|
||||
return esp_rmaker_int(val->val.i16);
|
||||
} else if (val->type == ESP_MATTER_VAL_TYPE_UINT16) {
|
||||
return esp_rmaker_int(val->val.u16);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid val type: %d", val->type);
|
||||
}
|
||||
return esp_rmaker_int(0);
|
||||
}
|
||||
|
||||
static esp_matter_attr_val_t app_rainmaker_get_matter_val(esp_rmaker_param_val_t *val, uint32_t cluster_id,
|
||||
uint32_t attribute_id)
|
||||
{
|
||||
/* Attributes which need to be remapped */
|
||||
if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
uint8_t value = REMAP_TO_RANGE(val->val.i, STANDARD_BRIGHTNESS, MATTER_BRIGHTNESS);
|
||||
return esp_matter_uint8(value);
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
uint8_t value = REMAP_TO_RANGE(val->val.i, STANDARD_HUE, MATTER_HUE);
|
||||
return esp_matter_uint8(value);
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
uint8_t value = REMAP_TO_RANGE(val->val.i, STANDARD_SATURATION, MATTER_SATURATION);
|
||||
return esp_matter_uint8(value);
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
uint16_t value = REMAP_TO_RANGE_INVERSE(val->val.i, MATTER_TEMPERATURE_FACTOR);
|
||||
return esp_matter_uint16(value);
|
||||
}
|
||||
}
|
||||
|
||||
/* Attributes which don't need to be remapped */
|
||||
if (val->type == RMAKER_VAL_TYPE_BOOLEAN) {
|
||||
return esp_matter_bool(val->val.b);
|
||||
} else if (val->type == RMAKER_VAL_TYPE_INTEGER) {
|
||||
return esp_matter_int(val->val.i);
|
||||
} else if (val->type == RMAKER_VAL_TYPE_FLOAT) {
|
||||
return esp_matter_float(val->val.f);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Invalid val type: %d", val->type);
|
||||
}
|
||||
return esp_matter_int(0);
|
||||
}
|
||||
|
||||
static const char *app_rainmaker_get_device_name_from_id(uint32_t endpoint_id)
|
||||
{
|
||||
if (endpoint_id == light_endpoint_id) {
|
||||
return DEFAULT_LIGHT_NAME;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *app_rainmaker_get_device_type_from_id(uint32_t device_type_id)
|
||||
{
|
||||
if (device_type_id == endpoint::color_temperature_light::get_device_type_id()) {
|
||||
return ESP_RMAKER_DEVICE_LIGHTBULB;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static uint16_t app_rainmaker_get_endpoint_id_from_name(const char *device_name)
|
||||
{
|
||||
if (strcmp(device_name, DEFAULT_LIGHT_NAME) == 0) {
|
||||
return light_endpoint_id;
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
static const char *app_rainmaker_get_param_name_from_id(uint32_t cluster_id, uint32_t attribute_id)
|
||||
{
|
||||
if (cluster_id == OnOff::Id) {
|
||||
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||
return ESP_RMAKER_DEF_POWER_NAME;
|
||||
}
|
||||
} else if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
return ESP_RMAKER_DEF_BRIGHTNESS_NAME;
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
return ESP_RMAKER_DEF_HUE_NAME;
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
return ESP_RMAKER_DEF_SATURATION_NAME;
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
return ESP_RMAKER_DEF_CCT_NAME;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *app_rainmaker_get_param_type_from_id(uint32_t cluster_id, uint32_t attribute_id)
|
||||
{
|
||||
if (cluster_id == OnOff::Id) {
|
||||
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||
return ESP_RMAKER_PARAM_POWER;
|
||||
}
|
||||
} else if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
return ESP_RMAKER_PARAM_BRIGHTNESS;
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
return ESP_RMAKER_PARAM_HUE;
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
return ESP_RMAKER_PARAM_SATURATION;
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
return ESP_RMAKER_PARAM_CCT;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *app_rainmaker_get_param_ui_type_from_id(uint32_t cluster_id, uint32_t attribute_id)
|
||||
{
|
||||
if (cluster_id == OnOff::Id) {
|
||||
if (attribute_id == OnOff::Attributes::OnOff::Id) {
|
||||
return ESP_RMAKER_UI_TOGGLE;
|
||||
}
|
||||
} else if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
return ESP_RMAKER_UI_SLIDER;
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
return ESP_RMAKER_UI_HUE_SLIDER;
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
return ESP_RMAKER_UI_SLIDER;
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
return ESP_RMAKER_UI_SLIDER;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool app_rainmaker_get_param_bounds_from_id(uint32_t cluster_id, uint32_t attribute_id, int *min, int *max,
|
||||
int *step)
|
||||
{
|
||||
if (cluster_id == LevelControl::Id) {
|
||||
if (attribute_id == LevelControl::Attributes::CurrentLevel::Id) {
|
||||
*min = 0;
|
||||
*max = STANDARD_BRIGHTNESS;
|
||||
*step = 1;
|
||||
return true;
|
||||
}
|
||||
} else if (cluster_id == ColorControl::Id) {
|
||||
if (attribute_id == ColorControl::Attributes::CurrentHue::Id) {
|
||||
*min = 0;
|
||||
*max = STANDARD_HUE;
|
||||
*step = 1;
|
||||
return true;
|
||||
} else if (attribute_id == ColorControl::Attributes::CurrentSaturation::Id) {
|
||||
*min = 0;
|
||||
*max = STANDARD_SATURATION;
|
||||
*step = 1;
|
||||
return true;
|
||||
} else if (attribute_id == ColorControl::Attributes::ColorTemperature::Id) {
|
||||
*min = 2700;
|
||||
*max = 6500;
|
||||
*step = 100;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static esp_err_t app_rainmaker_param_add_ui_type(esp_rmaker_param_t *param, cluster_t *cluster, attribute_t *attribute)
|
||||
{
|
||||
uint32_t cluster_id = cluster::get_id(cluster);
|
||||
uint32_t attribute_id = attribute::get_id(attribute);
|
||||
const char *ui_type = app_rainmaker_get_param_ui_type_from_id(cluster_id, attribute_id);
|
||||
if (!ui_type) {
|
||||
return ESP_OK;
|
||||
}
|
||||
return esp_rmaker_param_add_ui_type(param, ui_type);
|
||||
}
|
||||
|
||||
static esp_err_t app_rainmaker_param_add_bounds(esp_rmaker_param_t *param, cluster_t *cluster, attribute_t *attribute)
|
||||
{
|
||||
uint32_t cluster_id = cluster::get_id(cluster);
|
||||
uint32_t attribute_id = attribute::get_id(attribute);
|
||||
esp_matter_attr_bounds_t *bounds = attribute::get_bounds(attribute);
|
||||
if (bounds) {
|
||||
esp_rmaker_param_val_t min_val = app_rainmaker_get_rmaker_val(&bounds->min, cluster_id, attribute_id);
|
||||
esp_rmaker_param_val_t max_val = app_rainmaker_get_rmaker_val(&bounds->max, cluster_id, attribute_id);
|
||||
esp_rmaker_param_val_t step_val = esp_rmaker_int(1);
|
||||
return esp_rmaker_param_add_bounds(param, min_val, max_val, step_val);
|
||||
}
|
||||
|
||||
/* If bounds are not set for the attribute, check if there are any bounds to be added based on the id */
|
||||
int min = 0, max = 0, step = 0;
|
||||
bool add_bounds = app_rainmaker_get_param_bounds_from_id(cluster_id, attribute_id, &min, &max, &step);
|
||||
if (add_bounds) {
|
||||
esp_rmaker_param_val_t min_val = esp_rmaker_int(min);
|
||||
esp_rmaker_param_val_t max_val = esp_rmaker_int(max);
|
||||
esp_rmaker_param_val_t step_val = esp_rmaker_int(step);
|
||||
return esp_rmaker_param_add_bounds(param, min_val, max_val, step_val);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t app_rainmaker_get_cluster_id_from_name(const char *param_name)
|
||||
{
|
||||
if (strcmp(param_name, ESP_RMAKER_DEF_POWER_NAME) == 0) {
|
||||
return OnOff::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_BRIGHTNESS_NAME) == 0) {
|
||||
return LevelControl::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_HUE_NAME) == 0) {
|
||||
return ColorControl::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_SATURATION_NAME) == 0) {
|
||||
return ColorControl::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_CCT_NAME) == 0) {
|
||||
return ColorControl::Id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t app_rainmaker_get_attribute_id_from_name(const char *param_name)
|
||||
{
|
||||
if (strcmp(param_name, ESP_RMAKER_DEF_POWER_NAME) == 0) {
|
||||
return OnOff::Attributes::OnOff::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_BRIGHTNESS_NAME) == 0) {
|
||||
return LevelControl::Attributes::CurrentLevel::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_HUE_NAME) == 0) {
|
||||
return ColorControl::Attributes::CurrentHue::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_SATURATION_NAME) == 0) {
|
||||
return ColorControl::Attributes::CurrentSaturation::Id;
|
||||
} else if (strcmp(param_name, ESP_RMAKER_DEF_CCT_NAME) == 0) {
|
||||
return ColorControl::Attributes::ColorTemperature::Id;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_err_t app_rainmaker_attribute_update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||
esp_matter_attr_val_t *val)
|
||||
{
|
||||
const char *device_name = app_rainmaker_get_device_name_from_id(endpoint_id);
|
||||
const char *param_name = app_rainmaker_get_param_name_from_id(cluster_id, attribute_id);
|
||||
if (!device_name || !param_name) {
|
||||
ESP_LOGD(TAG, "Device name or param name not handled");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
const esp_rmaker_node_t *node = esp_rmaker_get_node();
|
||||
esp_rmaker_device_t *device = esp_rmaker_node_get_device_by_name(node, device_name);
|
||||
esp_rmaker_param_t *param = esp_rmaker_device_get_param_by_name(device, param_name);
|
||||
esp_rmaker_param_val_t rmaker_val = app_rainmaker_get_rmaker_val(val, cluster_id, attribute_id);
|
||||
if (!param) {
|
||||
ESP_LOGE(TAG, "Param not found");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return esp_rmaker_param_update_and_report(param, rmaker_val);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
if (ctx) {
|
||||
ESP_LOGI(TAG, "Received write request via : %s", esp_rmaker_device_cb_src_to_str(ctx->src));
|
||||
}
|
||||
|
||||
const char *device_name = esp_rmaker_device_get_name(device);
|
||||
const char *param_name = esp_rmaker_param_get_name(param);
|
||||
|
||||
uint16_t endpoint_id = app_rainmaker_get_endpoint_id_from_name(device_name);
|
||||
uint32_t cluster_id = app_rainmaker_get_cluster_id_from_name(param_name);
|
||||
uint32_t attribute_id = app_rainmaker_get_attribute_id_from_name(param_name);
|
||||
esp_matter_attr_val_t matter_val = app_rainmaker_get_matter_val((esp_rmaker_param_val_t *)&val, cluster_id,
|
||||
attribute_id);
|
||||
|
||||
return attribute::update(endpoint_id, cluster_id, attribute_id, &matter_val);
|
||||
}
|
||||
|
||||
static esp_rmaker_device_t *app_rainmaker_device_create(const esp_rmaker_node_t *node, endpoint_t *endpoint)
|
||||
{
|
||||
uint16_t endpoint_id = endpoint::get_id(endpoint);
|
||||
const char *device_name = app_rainmaker_get_device_name_from_id(endpoint_id);
|
||||
if (!device_name) {
|
||||
return NULL;
|
||||
}
|
||||
/* Add this device only if endpoint_id has been handled */
|
||||
uint32_t device_type_id = endpoint::get_device_type_id(endpoint);
|
||||
const char *device_type = app_rainmaker_get_device_type_from_id(device_type_id);
|
||||
esp_rmaker_device_t *device = esp_rmaker_device_create(device_name, device_type, NULL);
|
||||
if (!device) {
|
||||
ESP_LOGE(TAG, "Could not create rainmaker device");
|
||||
return NULL;
|
||||
}
|
||||
esp_rmaker_device_add_cb(device, write_cb, NULL);
|
||||
esp_rmaker_node_add_device(node, device);
|
||||
return device;
|
||||
}
|
||||
|
||||
static esp_rmaker_param_t *app_rainmaker_param_create(esp_rmaker_device_t *device, cluster_t *cluster,
|
||||
attribute_t *attribute)
|
||||
{
|
||||
uint32_t cluster_id = cluster::get_id(cluster);
|
||||
uint32_t attribute_id = attribute::get_id(attribute);
|
||||
const char *param_name = app_rainmaker_get_param_name_from_id(cluster_id, attribute_id);
|
||||
if (!param_name) {
|
||||
return NULL;
|
||||
}
|
||||
/* Add this param only if attribute_id corresponding to the cluster_id is handled */
|
||||
const char *param_type = app_rainmaker_get_param_type_from_id(cluster_id, attribute_id);
|
||||
esp_matter_attr_val_t val = esp_matter_invalid(NULL);
|
||||
attribute::get_val(attribute, &val);
|
||||
esp_rmaker_param_val_t rmaker_val = app_rainmaker_get_rmaker_val(&val, cluster_id, attribute_id);
|
||||
esp_rmaker_param_t *param = esp_rmaker_param_create(param_name, param_type, rmaker_val,
|
||||
PROP_FLAG_READ | PROP_FLAG_WRITE);
|
||||
if (!param) {
|
||||
ESP_LOGE(TAG, "Could not create rainmaker param");
|
||||
return NULL;
|
||||
}
|
||||
/* Add additional param details */
|
||||
app_rainmaker_param_add_ui_type(param, cluster, attribute);
|
||||
app_rainmaker_param_add_bounds(param, cluster, attribute);
|
||||
esp_rmaker_device_add_param(device, param);
|
||||
if (strcmp(param_type, ESP_RMAKER_PARAM_POWER) == 0) {
|
||||
esp_rmaker_device_assign_primary_param(device, param);
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
static void app_rainmaker_data_model_create()
|
||||
{
|
||||
const esp_rmaker_node_t *node = esp_rmaker_get_node();
|
||||
node_t *matter_node = node::get();
|
||||
endpoint_t *endpoint = endpoint::get_first(matter_node);
|
||||
|
||||
/* Parse all endpoints */
|
||||
while (endpoint) {
|
||||
esp_rmaker_device_t *device = app_rainmaker_device_create(node, endpoint);
|
||||
/* Proceed only if the device has been handled */
|
||||
if (device) {
|
||||
cluster_t *cluster = cluster::get_first(endpoint);
|
||||
/* Parse all clusters */
|
||||
while (cluster) {
|
||||
attribute_t *attribute = attribute::get_first(cluster);
|
||||
/* Parse all attributes */
|
||||
while (attribute) {
|
||||
app_rainmaker_param_create(device, cluster, attribute);
|
||||
attribute = attribute::get_next(attribute);
|
||||
}
|
||||
cluster = cluster::get_next(cluster);
|
||||
}
|
||||
}
|
||||
endpoint = endpoint::get_next(endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t app_rainmaker_init()
|
||||
{
|
||||
/* Add custom rainmaker cluster */
|
||||
return rainmaker::init();
|
||||
}
|
||||
|
||||
esp_err_t app_rainmaker_start()
|
||||
{
|
||||
/* Initialize the ESP RainMaker Agent.
|
||||
* Note that this should be called after app_wifi_init() but before app_wifi_start()
|
||||
* */
|
||||
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);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Create the rainmaker device and its params from matter data model */
|
||||
app_rainmaker_data_model_create();
|
||||
|
||||
/* Enable OTA */
|
||||
esp_rmaker_ota_config_t ota_config = {
|
||||
.server_cert = ESP_RMAKER_OTA_DEFAULT_SERVER_CERT,
|
||||
};
|
||||
esp_rmaker_ota_enable(&ota_config, OTA_USING_PARAMS);
|
||||
|
||||
/* 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();
|
||||
|
||||
/* Start the ESP RainMaker Agent */
|
||||
rainmaker::start();
|
||||
esp_rmaker_start();
|
||||
return ESP_OK;
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
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 <esp_err.h>
|
||||
#include <esp_matter.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Initialize ESP RainMaker
|
||||
*
|
||||
* This adds the custom RainMaker cluster.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_rainmaker_init(void);
|
||||
|
||||
/** Start ESP RainMaker
|
||||
*
|
||||
* This initializes the devices and params for RainMaker, corresponding to the endpoint and attributes. It also adds
|
||||
* RainMaker features like OTA, Scheduling, etc.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_rainmaker_start(void);
|
||||
|
||||
/** ESP RainMaker Update
|
||||
*
|
||||
* This API should be called to update ESP RainMaker for the attribute being updated.
|
||||
* This is usually called from the common `app_attribute_update_cb()`.
|
||||
*
|
||||
* @param[in] endpoint_id Endpoint ID of the attribute.
|
||||
* @param[in] cluster_id Cluster ID of the attribute.
|
||||
* @param[in] attribute_id Attribute ID of the attribute.
|
||||
* @param[in] val Pointer to `esp_matter_attr_val_t`. Use appropriate elements as per the value type.
|
||||
*
|
||||
* @return ESP_OK on success.
|
||||
* @return error in case of failure.
|
||||
*/
|
||||
esp_err_t app_rainmaker_attribute_update(uint16_t endpoint_id, uint32_t cluster_id, uint32_t attribute_id,
|
||||
esp_matter_attr_val_t *val);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2022 Project CHIP Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// THIS FILE IS GENERATED BY ZAP
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <esp_matter_cluster.h>
|
||||
|
||||
#define MATTER_PLUGINS_INIT esp_matter::cluster::plugin_init_callback_common();
|
||||
@@ -1,71 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2020 Project CHIP Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2020 Silicon Labs
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// This file is generated by Simplicity Studio. Please do not edit manually.
|
||||
//
|
||||
//
|
||||
|
||||
// Enclosing macro to prevent multiple inclusion
|
||||
#ifndef __AF_GEN_EVENT__
|
||||
#define __AF_GEN_EVENT__
|
||||
|
||||
// Code used to configure the cluster event mechanism
|
||||
#define EMBER_AF_GENERATED_EVENT_CODE \
|
||||
EmberEventControl emberAfLevelControlClusterServerTickCallbackControl1; \
|
||||
static void clusterTickWrapper(EmberEventControl * control, EmberAfTickFunction callback, uint8_t endpoint) \
|
||||
{ \
|
||||
/* emberAfPushEndpointNetworkIndex(endpoint); */ \
|
||||
emberEventControlSetInactive(control); \
|
||||
(*callback)(endpoint); \
|
||||
/* emberAfPopNetworkIndex(); */ \
|
||||
} \
|
||||
void emberAfLevelControlClusterServerTickCallbackWrapperFunction1(void) \
|
||||
{ \
|
||||
clusterTickWrapper(&emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallback, \
|
||||
1); \
|
||||
}
|
||||
|
||||
// EmberEventData structs used to populate the EmberEventData table
|
||||
#define EMBER_AF_GENERATED_EVENTS \
|
||||
{ &emberAfLevelControlClusterServerTickCallbackControl1, emberAfLevelControlClusterServerTickCallbackWrapperFunction1 },
|
||||
|
||||
#define EMBER_AF_GENERATED_EVENT_STRINGS "Level Control Cluster Server EP 1",
|
||||
|
||||
// The length of the event context table used to track and retrieve cluster events
|
||||
#define EMBER_AF_EVENT_CONTEXT_LENGTH 1
|
||||
|
||||
// EmberAfEventContext structs used to populate the EmberAfEventContext table
|
||||
#define EMBER_AF_GENERATED_EVENT_CONTEXT \
|
||||
{ 0x1, 0x8, false, EMBER_AF_LONG_POLL, EMBER_AF_OK_TO_SLEEP, &emberAfLevelControlClusterServerTickCallbackControl1 },
|
||||
|
||||
#endif // __AF_GEN_EVENT__
|
||||
@@ -1,8 +0,0 @@
|
||||
/** Empty File
|
||||
*
|
||||
* This file is just present to prevent cmake warnings about:
|
||||
* No source files found for SRC_DIRS entry '/Users/chirag/work/gitlab/esp-matter/examples/<name>/main/zap-generated'.
|
||||
*
|
||||
* We need to keep the path in SRC_DIRS to be compatible with the zap data model.
|
||||
*/
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2022 Project CHIP Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// THIS FILE IS GENERATED BY ZAP
|
||||
|
||||
// Prevent multiple inclusion
|
||||
#pragma once
|
||||
|
||||
#include <lib/core/CHIPConfig.h>
|
||||
|
||||
#define GENERATED_ATTRIBUTES \
|
||||
{}
|
||||
|
||||
#define GENERATED_CLUSTERS \
|
||||
{}
|
||||
|
||||
#define GENERATED_ENDPOINT_TYPES \
|
||||
{}
|
||||
|
||||
#define ZAP_FIXED_ENDPOINT_DATA_VERSION_COUNT 0
|
||||
|
||||
// Largest attribute size is needed for various buffers
|
||||
#define ATTRIBUTE_LARGEST (259)
|
||||
|
||||
static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, "ATTRIBUTE_LARGEST larger than expected");
|
||||
|
||||
// Total size of attribute storage
|
||||
#define ATTRIBUTE_MAX_SIZE (0)
|
||||
|
||||
// Number of fixed endpoints
|
||||
#define FIXED_ENDPOINT_COUNT (0)
|
||||
#ifdef CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT
|
||||
#undef CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT
|
||||
#endif
|
||||
#define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT (16)
|
||||
|
||||
// Array of endpoints that are supported, the data inside
|
||||
// the array is the endpoint number.
|
||||
#define FIXED_ENDPOINT_ARRAY \
|
||||
{0}
|
||||
|
||||
// Array of profile ids
|
||||
#define FIXED_PROFILE_IDS \
|
||||
{0}
|
||||
|
||||
// Array of device types
|
||||
#define FIXED_DEVICE_TYPES \
|
||||
{0}
|
||||
|
||||
// Array of device type offsets
|
||||
#define FIXED_DEVICE_TYPE_OFFSETS \
|
||||
{0}
|
||||
|
||||
// Array of device type lengths
|
||||
#define FIXED_DEVICE_TYPE_LENGTHS \
|
||||
{0}
|
||||
|
||||
// Array of endpoint types supported on each endpoint
|
||||
#define FIXED_ENDPOINT_TYPES \
|
||||
{0}
|
||||
|
||||
// Array of networks supported on each endpoint
|
||||
#define FIXED_NETWORKS \
|
||||
{0}
|
||||
@@ -1,9 +0,0 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table
|
||||
sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition
|
||||
nvs, data, nvs, 0x10000, 0x6000,
|
||||
otadata, data, ota, , 0x2000
|
||||
phy_init, data, phy, , 0x1000,
|
||||
ota_0, app, ota_0, 0x20000, 0x1E0000,
|
||||
ota_1, app, ota_1, 0x200000, 0x1E0000,
|
||||
fctry, data, nvs, 0x3E0000, 0x6000
|
||||
|
@@ -1,43 +0,0 @@
|
||||
# Default to 921600 baud when flashing and monitoring device
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_BAUD=921600
|
||||
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
|
||||
#enable BT
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
|
||||
#enable lwip ipv6 autoconfig
|
||||
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||
|
||||
# Use a custom partition table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
|
||||
# Enable chip shell
|
||||
CONFIG_ENABLE_CHIP_SHELL=y
|
||||
|
||||
# mbedtls
|
||||
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
||||
CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y
|
||||
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
|
||||
|
||||
# Temporary Fix for Timer Overflows
|
||||
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120
|
||||
|
||||
#enable lwIP route hooks
|
||||
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||
|
||||
# Button
|
||||
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||
|
||||
# ESP RainMaker
|
||||
CONFIG_ESP_RMAKER_USER_ID_CHECK=y
|
||||
CONFIG_ESP_RMAKER_SELF_CLAIM=y
|
||||
@@ -1,41 +0,0 @@
|
||||
# Default to 921600 baud when flashing and monitoring device
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_BAUD=921600
|
||||
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||
|
||||
#enable lwip ipv6 autoconfig
|
||||
CONFIG_LWIP_IPV6_AUTOCONFIG=y
|
||||
|
||||
# Use a custom partition table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||
CONFIG_PARTITION_TABLE_MD5=y
|
||||
|
||||
# Enable chip shell
|
||||
CONFIG_ENABLE_CHIP_SHELL=y
|
||||
|
||||
# mbedtls
|
||||
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
|
||||
CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y
|
||||
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
|
||||
|
||||
# Temporary Fix for Timer Overflows
|
||||
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3120
|
||||
|
||||
#enable lwIP route hooks
|
||||
CONFIG_LWIP_HOOK_IP6_ROUTE_DEFAULT=y
|
||||
CONFIG_LWIP_HOOK_ND6_GET_GW_DEFAULT=y
|
||||
|
||||
# Button
|
||||
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||
|
||||
# ESP RainMaker
|
||||
CONFIG_ESP_RMAKER_USER_ID_CHECK=y
|
||||
|
||||
# Disable BLE
|
||||
CONFIG_ENABLE_CHIPOBLE=n
|
||||
Reference in New Issue
Block a user