mirror of
https://github.com/espressif/esp-matter.git
synced 2026-04-27 19:13:13 +00:00
Add generic_switch example and mapping of switch events to button
This commit is contained in:
@@ -779,5 +779,128 @@ esp_err_t add(cluster_t *cluster, config_t *config)
|
||||
} /* feature */
|
||||
} /* thermostat */
|
||||
|
||||
namespace switch_cluster {
|
||||
namespace feature {
|
||||
namespace latching_switch {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
// The SwitchFeature enum class is not added in the upstream code.
|
||||
// Return the code according to the SPEC
|
||||
return (uint32_t)0x01;
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster)
|
||||
{
|
||||
if((get_feature_map_value(cluster) & feature::momentary_switch::get_id()) == feature::momentary_switch::get_id())
|
||||
{
|
||||
ESP_LOGE(TAG, "Latching switch is not supported because momentary switch is present");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} /* latching_switch */
|
||||
|
||||
namespace momentary_switch {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
// The SwitchFeature enum class is not added in the upstream code.
|
||||
// Return the code according to the SPEC
|
||||
return (uint32_t)0x02;
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster)
|
||||
{
|
||||
if((get_feature_map_value(cluster) & feature::latching_switch::get_id()) == feature::latching_switch::get_id())
|
||||
{
|
||||
ESP_LOGE(TAG, "Momentary switch is not supported because latching switch is present");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} /* momentary_switch */
|
||||
|
||||
namespace momentary_switch_release {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
// The SwitchFeature enum class is not added in the upstream code.
|
||||
// Return the code according to the SPEC
|
||||
return (uint32_t)0x04;
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster)
|
||||
{
|
||||
if((get_feature_map_value(cluster) & feature::momentary_switch::get_id()) != feature::momentary_switch::get_id())
|
||||
{
|
||||
ESP_LOGE(TAG, "Momentary switch release is not supported because momentary is absent");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} /* momentary_switch_release */
|
||||
|
||||
namespace momentary_switch_long_press {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
// The SwitchFeature enum class is not added in the upstream code.
|
||||
// Return the code according to the SPEC
|
||||
return (uint32_t)0x08;
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster)
|
||||
{
|
||||
uint32_t momentary_and_momentart_switch_release_feature_map = feature::momentary_switch::get_id() | feature::momentary_switch_release::get_id();
|
||||
if((get_feature_map_value(cluster) & momentary_and_momentart_switch_release_feature_map) != momentary_and_momentart_switch_release_feature_map)
|
||||
{
|
||||
ESP_LOGE(TAG, "Momentary switch long press is not supported because momentary switch and/or momentary switch release is absent");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} /* momentary_switch_long_press */
|
||||
|
||||
namespace momentary_switch_multi_press {
|
||||
|
||||
uint32_t get_id()
|
||||
{
|
||||
// The SwitchFeature enum class is not added in the upstream code.
|
||||
// Return the code according to the SPEC
|
||||
return (uint32_t)0x10;
|
||||
}
|
||||
|
||||
esp_err_t add(cluster_t *cluster, config_t *config)
|
||||
{
|
||||
uint32_t momentary_and_momentart_switch_release_feature_map = feature::momentary_switch::get_id() | feature::momentary_switch_release::get_id();
|
||||
if((get_feature_map_value(cluster) & momentary_and_momentart_switch_release_feature_map) != momentary_and_momentart_switch_release_feature_map)
|
||||
{
|
||||
ESP_LOGE(TAG, "Momentary switch multi press is not supported because momentary switch and/or momentary switch releaseis absent");
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
update_feature_map(cluster, get_id());
|
||||
|
||||
attribute::create_multi_press_max(cluster, config->multi_press_max);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
} /* momentary_switch_multi_press */
|
||||
} /* feature */
|
||||
} /* switch_cluster */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -359,5 +359,50 @@ esp_err_t add(cluster_t *cluster, config_t *config);
|
||||
} /* feature */
|
||||
} /* thermostat */
|
||||
|
||||
namespace switch_cluster {
|
||||
namespace feature {
|
||||
|
||||
namespace latching_switch {
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster);
|
||||
|
||||
} /* latching_switch */
|
||||
|
||||
namespace momentary_switch {
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster);
|
||||
|
||||
} /* momentary_switch */
|
||||
|
||||
namespace momentary_switch_release {
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster);
|
||||
|
||||
} /* momentary_switch_release */
|
||||
|
||||
namespace momentary_switch_long_press {
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster);
|
||||
|
||||
} /* momentary_switch_long_press */
|
||||
|
||||
namespace momentary_switch_multi_press {
|
||||
|
||||
typedef struct config {
|
||||
uint8_t multi_press_max;
|
||||
config() : multi_press_max(2) {}
|
||||
} config_t;
|
||||
|
||||
uint32_t get_id();
|
||||
esp_err_t add(cluster_t *cluster, config_t *config);
|
||||
|
||||
} /* momentary_switch_multi_pressy */
|
||||
} /* feature */
|
||||
} /* switch_cluster */
|
||||
|
||||
} /* cluster */
|
||||
} /* esp_matter */
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
# 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 "esp32h2")
|
||||
set(ENV{ESP_MATTER_DEVICE_PATH} $ENV{ESP_MATTER_PATH}/device_hal/device/esp32h2_devkit_c)
|
||||
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(PROJECT_VER "v1.0")
|
||||
set(PROJECT_VER_NUMBER 1)
|
||||
|
||||
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)
|
||||
|
||||
# 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)
|
||||
|
||||
set(EXTRA_COMPONENT_DIRS
|
||||
"${ESP_MATTER_PATH}/examples/common"
|
||||
"${MATTER_SDK_PATH}/config/esp32/components"
|
||||
"${ESP_MATTER_PATH}/components"
|
||||
"${ESP_MATTER_PATH}/device_hal/device"
|
||||
${extra_components_dirs_append})
|
||||
|
||||
project(generic_switch)
|
||||
|
||||
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++14;-Os;-DCHIP_HAVE_CONFIG_H" APPEND)
|
||||
idf_build_set_property(C_COMPILE_OPTIONS "-Os" 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;-Wformat=0" APPEND)
|
||||
@@ -0,0 +1,59 @@
|
||||
# Generic Switch
|
||||
|
||||
This example creates a Generic Switch device using the ESP
|
||||
Matter data model.
|
||||
|
||||
See the [docs](https://docs.espressif.com/projects/esp-matter/en/main/esp32/developing.html) for more information about building and flashing the firmware.
|
||||
|
||||
## 1. Additional Environment Setup
|
||||
|
||||
No additional setup is required.
|
||||
|
||||
## 2. Post Commissioning Setup
|
||||
|
||||
This should be followed by: Commission the generic switch device
|
||||
- Turn on chip-tool interactive mode. ``./chip-tool interactive start``
|
||||
- By default latching switch is enabled so subscribe to switch-latched event via chip-tool.
|
||||
``switch subscribe-event switch-latched <min-interval> <max-interval> <destination-id> <endpoint-id>``
|
||||
- `Double press the boot button` on device so that client will receive event after max-interval.
|
||||
|
||||
### 2.1 Latching switch
|
||||
|
||||
Following are latching switch events mapped with boot button on device.
|
||||
|
||||
- `Double Press` -----------> `switch-latched`
|
||||
|
||||
### 2.2 Momentary switch
|
||||
|
||||
Following are momentary switch events mapped with boot button on device.
|
||||
|
||||
- `Button Press Down` -----------> `initial-pressed`
|
||||
- `Button Press Up ( Release )` -----------> `short-release`
|
||||
- `Button Long Press ( 5 sec )` -----------> `long-pressed`
|
||||
- `Button Press Up ( Long Release )` -----------> `long-release`
|
||||
- `Button Press Repeat` -----------> `multipress-ongoing`
|
||||
- `Button Press Repeat Done` -----------> `multipress-completed`
|
||||
|
||||
## 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:
|
||||
[4881109](https://github.com/espressif/esp-matter/commit/4881109ce26c92e547ca11d6f022d2c9f908834e)
|
||||
(2022-12-15)
|
||||
|
||||
| | Bootup | After Commissioning |
|
||||
|:- |:-: |:-: |
|
||||
|**Free Internal Memory** |94KB |110KB |
|
||||
|
||||
**Flash Usage**: Firmware binary size: 1.24MB
|
||||
|
||||
This should give you a good idea about the amount of free memory that is
|
||||
available for you to run your application's code.
|
||||
@@ -0,0 +1,8 @@
|
||||
set(PRIV_REQUIRES_LIST device esp_matter esp_matter_console route_hook app_reset)
|
||||
|
||||
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 "-DCHIP_HAVE_CONFIG_H")
|
||||
@@ -0,0 +1,14 @@
|
||||
menu "Demo"
|
||||
config GENERIC_SWITCH_TYPE
|
||||
choice
|
||||
prompt "Generic Switch Type"
|
||||
default GENERIC_SWITCH_TYPE_LATCHING
|
||||
help
|
||||
Define type of switch is latching or momentary.
|
||||
|
||||
config GENERIC_SWITCH_TYPE_LATCHING
|
||||
bool "Generic Switch Type Latching"
|
||||
config GENERIC_SWITCH_TYPE_MOMENTARY
|
||||
bool "Generic Switch Type Momentary"
|
||||
endchoice
|
||||
endmenu
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
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 <app-common/zap-generated/attributes/Accessors.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
|
||||
using namespace chip::app::Clusters;
|
||||
using namespace esp_matter;
|
||||
using namespace esp_matter::cluster;
|
||||
|
||||
static const char *TAG = "app_driver";
|
||||
extern uint16_t switch_endpoint_id;
|
||||
|
||||
esp_err_t app_driver_attribute_update(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
|
||||
static void app_driver_button_switch_latched(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Switch lached pressed");
|
||||
|
||||
// Press moves Position from 0 (idle) to 1 (press)
|
||||
uint8_t newPosition = 1;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// SwitchLatched event takes newPosition as event data
|
||||
switch_cluster::event::send_switch_latched(switch_endpoint_id, newPosition);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
|
||||
static void app_driver_button_initial_pressed(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Initial button pressed");
|
||||
|
||||
// Press moves Position from 0 (idle) to 1 (press)
|
||||
uint8_t newPosition = 1;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// InitialPress event takes newPosition as event data
|
||||
switch_cluster::event::send_initial_press(switch_endpoint_id, newPosition);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
|
||||
static void app_driver_button_release(void *arg, void *data)
|
||||
{
|
||||
if(iot_button_get_ticks_time((button_handle_t)arg) < 5000){
|
||||
ESP_LOGI(TAG, "Short button release");
|
||||
|
||||
// Release moves Position from 1 (press) to 0 (idle)
|
||||
uint8_t previousPosition = 1;
|
||||
uint8_t newPosition = 0;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// ShortRelease event takes previousPosition as event data
|
||||
switch_cluster::event::send_short_release(switch_endpoint_id, previousPosition);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
else{
|
||||
ESP_LOGI(TAG, "Long button release");
|
||||
|
||||
// Release moves Position from 1 (press) to 0 (idle)
|
||||
uint8_t previousPosition = 1;
|
||||
uint8_t newPosition = 0;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// LongRelease event takes previousPositionPosition as event data
|
||||
switch_cluster::event::send_long_release(switch_endpoint_id, previousPosition);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void app_driver_button_long_pressed(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Long button pressed");
|
||||
|
||||
// Press moves Position from 0 (idle) to 1 (press)
|
||||
uint8_t newPosition = 1;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// LongPress event takes newPosition as event data
|
||||
switch_cluster::event::send_long_press(switch_endpoint_id, newPosition);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
|
||||
static int current_number_of_presses_counted = 1;
|
||||
|
||||
static void app_driver_button_multipress_ongoing(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Multipress Ongoing");
|
||||
|
||||
// Press moves Position from 0 (idle) to 1 (press)
|
||||
uint8_t newPosition = 1;
|
||||
current_number_of_presses_counted++;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// MultiPress Ongoing event takes newPosition and current_number_of_presses_counted as event data
|
||||
switch_cluster::event::send_multi_press_ongoing(switch_endpoint_id, newPosition, current_number_of_presses_counted);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
|
||||
static void app_driver_button_multipress_complete(void *arg, void *data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Multipress Complete");
|
||||
|
||||
// Press moves Position from 0 (idle) to 1 (press)
|
||||
uint8_t previousPosition = 1;
|
||||
uint8_t newPosition = 0;
|
||||
static int total_number_of_presses_counted = current_number_of_presses_counted;
|
||||
lock::chip_stack_lock(portMAX_DELAY);
|
||||
chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(switch_endpoint_id, newPosition);
|
||||
// MultiPress Complete event takes previousPosition and total_number_of_presses_counted as event data
|
||||
switch_cluster::event::send_multi_press_complete(switch_endpoint_id, previousPosition, total_number_of_presses_counted);
|
||||
lock::chip_stack_unlock();
|
||||
}
|
||||
#endif
|
||||
|
||||
app_driver_handle_t app_driver_button_init()
|
||||
{
|
||||
/* Initialize button */
|
||||
button_config_t config = button_driver_get_config();
|
||||
button_handle_t handle = iot_button_create(&config);
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
|
||||
iot_button_register_cb(handle, BUTTON_DOUBLE_CLICK, app_driver_button_switch_latched, NULL);
|
||||
#endif
|
||||
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_initial_pressed, NULL);
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_UP, app_driver_button_release, NULL);
|
||||
iot_button_register_cb(handle, BUTTON_LONG_PRESS_START, app_driver_button_long_pressed, NULL);
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT, app_driver_button_multipress_ongoing, NULL);
|
||||
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT_DONE, app_driver_button_multipress_complete, NULL);
|
||||
#endif
|
||||
return (app_driver_handle_t)handle;
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
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_matter_ota.h>
|
||||
|
||||
#include <app_priv.h>
|
||||
#include <app_reset.h>
|
||||
|
||||
static const char *TAG = "app_main";
|
||||
uint16_t switch_endpoint_id = 0;
|
||||
|
||||
using namespace esp_matter;
|
||||
using namespace esp_matter::attribute;
|
||||
using namespace esp_matter::endpoint;
|
||||
using namespace chip::app::Clusters;
|
||||
|
||||
static void app_event_cb(const ChipDeviceEvent *event, intptr_t arg)
|
||||
{
|
||||
switch (event->Type) {
|
||||
case chip::DeviceLayer::DeviceEventType::kInterfaceIpAddressChanged:
|
||||
ESP_LOGI(TAG, "Interface IP Address changed");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete:
|
||||
ESP_LOGI(TAG, "Commissioning complete");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired:
|
||||
ESP_LOGI(TAG, "Commissioning failed, fail safe timer expired");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStarted:
|
||||
ESP_LOGI(TAG, "Commissioning session started");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningSessionStopped:
|
||||
ESP_LOGI(TAG, "Commissioning session stopped");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowOpened:
|
||||
ESP_LOGI(TAG, "Commissioning window opened");
|
||||
break;
|
||||
|
||||
case chip::DeviceLayer::DeviceEventType::kCommissioningWindowClosed:
|
||||
ESP_LOGI(TAG, "Commissioning window closed");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t app_identification_cb(identification::callback_type_t type, uint16_t endpoint_id, uint8_t effect_id,
|
||||
void *priv_data)
|
||||
{
|
||||
ESP_LOGI(TAG, "Identification callback: type: %d, effect: %d", type, effect_id);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t app_attribute_update_cb(attribute::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 */
|
||||
app_driver_handle_t driver_handle = (app_driver_handle_t)priv_data;
|
||||
err = app_driver_attribute_update(driver_handle, 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();
|
||||
|
||||
/* Initialize driver */
|
||||
app_driver_handle_t button_handle = app_driver_button_init();
|
||||
|
||||
/* Create a Matter node and add the mandatory Root Node device type on endpoint 0 */
|
||||
node::config_t node_config;
|
||||
node_t *node = node::create(&node_config, app_attribute_update_cb, app_identification_cb);
|
||||
|
||||
generic_switch::config_t switch_config;
|
||||
endpoint_t *endpoint = generic_switch::create(node, &switch_config, ENDPOINT_FLAG_NONE, button_handle);
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
switch_endpoint_id = endpoint::get_id(endpoint);
|
||||
ESP_LOGI(TAG, "Generic Switch created with endpoint_id %d", switch_endpoint_id);
|
||||
|
||||
/* Add additional features to the node */
|
||||
cluster_t *cluster = cluster::get(endpoint, Switch::Id);
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
|
||||
cluster::switch_cluster::feature::latching_switch::add(cluster);
|
||||
#endif
|
||||
|
||||
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
|
||||
cluster::switch_cluster::feature::momentary_switch::add(cluster);
|
||||
#endif
|
||||
/* Matter start */
|
||||
err = esp_matter::start(app_event_cb);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Matter start failed: %d", err);
|
||||
}
|
||||
|
||||
#if CONFIG_ENABLE_CHIP_SHELL
|
||||
esp_matter::console::diagnostics_register_commands();
|
||||
esp_matter::console::init();
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
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>
|
||||
|
||||
typedef void *app_driver_handle_t;
|
||||
|
||||
/** Initialize the button driver
|
||||
*
|
||||
* This initializes the button driver associated with the selected board.
|
||||
*
|
||||
* @return Handle on success.
|
||||
* @return NULL in case of failure.
|
||||
*/
|
||||
app_driver_handle_t app_driver_button_init();
|
||||
|
||||
/** 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(app_driver_handle_t driver_handle, uint16_t endpoint_id, uint32_t cluster_id,
|
||||
uint32_t attribute_id, esp_matter_attr_val_t *val);
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
*
|
||||
* 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();
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
*
|
||||
* 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__
|
||||
@@ -0,0 +1,7 @@
|
||||
/** 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.
|
||||
*/
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
*
|
||||
* 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}
|
||||
@@ -0,0 +1,9 @@
|
||||
# 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
|
||||
|
@@ -0,0 +1,8 @@
|
||||
# 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,
|
||||
phy_init, data, phy, , 0x1000,
|
||||
# Temporarily disable ota for ESP32-H2 because the use of flash need to be optimized.
|
||||
factory, app, factory, , 0x1C0000,
|
||||
ot_storage,data, fat, , 0x6000,
|
||||
|
@@ -0,0 +1,32 @@
|
||||
# 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"
|
||||
|
||||
# Enable chip shell
|
||||
CONFIG_ENABLE_CHIP_SHELL=y
|
||||
|
||||
#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
|
||||
|
||||
# disable softap by default
|
||||
CONFIG_ESP_WIFI_SOFTAP_SUPPORT=n
|
||||
@@ -0,0 +1,70 @@
|
||||
CONFIG_IDF_TARGET="esp32h2"
|
||||
CONFIG_IDF_TARGET_ESP32H2_BETA_VERSION_2=y
|
||||
|
||||
# Default to 921600 baud when flashing and monitoring device
|
||||
CONFIG_ESPTOOLPY_BAUD_921600B=y
|
||||
CONFIG_ESPTOOLPY_BAUD=921600
|
||||
CONFIG_ESPTOOLPY_COMPRESSED=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
|
||||
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD_115200B=y
|
||||
CONFIG_ESPTOOLPY_MONITOR_BAUD=115200
|
||||
CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y
|
||||
|
||||
# libsodium
|
||||
CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y
|
||||
|
||||
# NIMBLE
|
||||
CONFIG_BT_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_ENABLED=y
|
||||
CONFIG_BT_NIMBLE_EXT_ADV=n
|
||||
CONFIG_BT_NIMBLE_HCI_EVT_BUF_SIZE=70
|
||||
CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING=n
|
||||
|
||||
# FreeRTOS should use legacy API
|
||||
CONFIG_FREERTOS_ENABLE_BACKWARD_COMPATIBILITY=y
|
||||
|
||||
# Enable OpenThread
|
||||
CONFIG_OPENTHREAD_ENABLED=y
|
||||
CONFIG_OPENTHREAD_SRP_CLIENT=y
|
||||
|
||||
# Disable lwip ipv6 autoconfig
|
||||
CONFIG_LWIP_IPV6_AUTOCONFIG=n
|
||||
|
||||
# Use a custom partition table
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_h2.csv"
|
||||
|
||||
# LwIP config for OpenThread
|
||||
CONFIG_LWIP_IPV6_NUM_ADDRESSES=8
|
||||
CONFIG_LWIP_MULTICAST_PING=y
|
||||
|
||||
# mbedTLS
|
||||
CONFIG_MBEDTLS_HARDWARE_AES=n
|
||||
CONFIG_MBEDTLS_HARDWARE_MPI=n
|
||||
CONFIG_MBEDTLS_HARDWARE_SHA=n
|
||||
CONFIG_MBEDTLS_HARDWARE_ECC=y
|
||||
CONFIG_MBEDTLS_ATCA_HW_ECDSA_SIGN=n
|
||||
CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY=n
|
||||
CONFIG_MBEDTLS_CMAC_C=y
|
||||
CONFIG_MBEDTLS_SSL_PROTO_DTLS=y
|
||||
CONFIG_MBEDTLS_KEY_EXCHANGE_ECJPAKE=y
|
||||
|
||||
# MDNS platform
|
||||
CONFIG_USE_MINIMAL_MDNS=n
|
||||
CONFIG_ENABLE_EXTENDED_DISCOVERY=y
|
||||
|
||||
# Enable OTA Requestor
|
||||
CONFIG_ENABLE_OTA_REQUESTOR=n
|
||||
|
||||
# Disable STA and AP for ESP32H2
|
||||
CONFIG_ENABLE_WIFI_STATION=n
|
||||
CONFIG_ENABLE_WIFI_AP=n
|
||||
|
||||
# Button
|
||||
CONFIG_BUTTON_PERIOD_TIME_MS=20
|
||||
CONFIG_BUTTON_LONG_PRESS_TIME_MS=5000
|
||||
|
||||
# Enable chip shell
|
||||
CONFIG_ENABLE_CHIP_SHELL=y
|
||||
|
||||
Reference in New Issue
Block a user