|
|
|
@@ -10,11 +10,17 @@
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include "bsp/esp-bsp.h"
|
|
|
|
|
#include <esp_matter.h>
|
|
|
|
|
#include <app-common/zap-generated/attributes/Accessors.h>
|
|
|
|
|
|
|
|
|
|
#include <app_priv.h>
|
|
|
|
|
#include <iot_button.h>
|
|
|
|
|
|
|
|
|
|
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S3
|
|
|
|
|
#define BUTTON_GPIO_PIN GPIO_NUM_0
|
|
|
|
|
#else // CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2
|
|
|
|
|
#define BUTTON_GPIO_PIN GPIO_NUM_9
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
using namespace chip::app::Clusters;
|
|
|
|
|
using namespace esp_matter;
|
|
|
|
@@ -37,11 +43,11 @@ static void app_driver_button_switch_latched(void *arg, void *data)
|
|
|
|
|
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
|
|
|
|
|
// 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();
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
|
|
|
|
@@ -52,38 +58,39 @@ static void app_driver_button_initial_pressed(void *arg, void *data)
|
|
|
|
|
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
|
|
|
|
|
// 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();
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void app_driver_button_release(void *arg, void *data)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
gpio_button *button = (gpio_button *)data;
|
|
|
|
|
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
ESP_LOGI(TAG, "Long button release");
|
|
|
|
|
// Release moves Position from 1 (press) to 0 (idle)
|
|
|
|
|
uint8_t previousPosition = 1;
|
|
|
|
|
uint8_t newPosition = 0;
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -94,11 +101,11 @@ static void app_driver_button_long_pressed(void *arg, void *data)
|
|
|
|
|
int switch_endpoint_id = (button != NULL) ? get_endpoint(button) : 1;
|
|
|
|
|
// 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();
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int current_number_of_presses_counted = 1;
|
|
|
|
@@ -111,11 +118,11 @@ static void app_driver_button_multipress_ongoing(void *arg, void *data)
|
|
|
|
|
// 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();
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void app_driver_button_multipress_complete(void *arg, void *data)
|
|
|
|
@@ -126,33 +133,44 @@ static void app_driver_button_multipress_complete(void *arg, void *data)
|
|
|
|
|
// Press moves Position from 0 (idle) to 1 (press)
|
|
|
|
|
uint8_t previousPosition = 1;
|
|
|
|
|
uint8_t newPosition = 0;
|
|
|
|
|
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);
|
|
|
|
|
// Reset current_number_of_presses_counted to initial value
|
|
|
|
|
current_number_of_presses_counted = 1;
|
|
|
|
|
lock::chip_stack_unlock();
|
|
|
|
|
static int total_number_of_presses_counted = current_number_of_presses_counted;
|
|
|
|
|
chip::DeviceLayer::SystemLayer().ScheduleLambda([switch_endpoint_id, previousPosition, newPosition]() {
|
|
|
|
|
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);
|
|
|
|
|
// Reset current_number_of_presses_counted to initial value
|
|
|
|
|
current_number_of_presses_counted = 1;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
app_driver_handle_t app_driver_button_init(gpio_button * button)
|
|
|
|
|
{
|
|
|
|
|
/* Initialize button */
|
|
|
|
|
button_handle_t btns[BSP_BUTTON_NUM];
|
|
|
|
|
ESP_ERROR_CHECK(bsp_iot_button_create(btns, NULL, BSP_BUTTON_NUM));
|
|
|
|
|
button_config_t config = {
|
|
|
|
|
.type = BUTTON_TYPE_GPIO,
|
|
|
|
|
.gpio_button_config = {
|
|
|
|
|
.gpio_num = BUTTON_GPIO_PIN,
|
|
|
|
|
.active_level = 0,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (button != NULL) {
|
|
|
|
|
config.type = button_type_t::BUTTON_TYPE_GPIO;
|
|
|
|
|
config.gpio_button_config.gpio_num = button->GPIO_PIN_VALUE;
|
|
|
|
|
}
|
|
|
|
|
button_handle_t handle = iot_button_create(&config);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if CONFIG_GENERIC_SWITCH_TYPE_LATCHING
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_DOUBLE_CLICK, app_driver_button_switch_latched, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_DOUBLE_CLICK, app_driver_button_switch_latched, button);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#if CONFIG_GENERIC_SWITCH_TYPE_MOMENTARY
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_PRESS_DOWN, app_driver_button_initial_pressed, button);
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_PRESS_UP, app_driver_button_release, button);
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_LONG_PRESS_START, app_driver_button_long_pressed, button);
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_PRESS_REPEAT, app_driver_button_multipress_ongoing, button);
|
|
|
|
|
iot_button_register_cb(btns[0], BUTTON_PRESS_REPEAT_DONE, app_driver_button_multipress_complete, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_PRESS_DOWN, app_driver_button_initial_pressed, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_PRESS_UP, app_driver_button_release, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_LONG_PRESS_START, app_driver_button_long_pressed, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT, app_driver_button_multipress_ongoing, button);
|
|
|
|
|
iot_button_register_cb(handle, BUTTON_PRESS_REPEAT_DONE, app_driver_button_multipress_complete, button);
|
|
|
|
|
#endif
|
|
|
|
|
return (app_driver_handle_t)btns[0];
|
|
|
|
|
return (app_driver_handle_t)handle;
|
|
|
|
|
}
|
|
|
|
|