From d9e038d63e056112751df8c9fc4914a42e7983c5 Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Mon, 11 Nov 2024 23:20:39 +0700 Subject: [PATCH 1/6] feat: SmartButton --- changelog.md | 3 + library.json | 2 +- library.properties | 2 +- src/Capabilities/SmartButtonStateController.h | 131 ++++++++++++++++++ 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 src/Capabilities/SmartButtonStateController.h diff --git a/changelog.md b/changelog.md index 7cfe062..de04657 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,8 @@ # Changelog +## Version 3.3.1 + - Support SmartButton. + ## Version 3.2.1 - Fixed Arduino Lint errors - LICENSE.txt added diff --git a/library.json b/library.json index d6440f5..8e5b45c 100644 --- a/library.json +++ b/library.json @@ -13,7 +13,7 @@ "maintainer": true } ], - "version": "3.2.1", + "version": "3.3.1", "frameworks": "arduino", "platforms": [ "espressif8266", diff --git a/library.properties b/library.properties index 6d52c19..5bf0048 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=SinricPro -version=3.2.1 +version=3.3.1 author=Boris Jaeger maintainer=Boris Jaeger sentence=Library for https://sinric.pro - simple way to connect your device to alexa diff --git a/src/Capabilities/SmartButtonStateController.h b/src/Capabilities/SmartButtonStateController.h new file mode 100644 index 0000000..b26c038 --- /dev/null +++ b/src/Capabilities/SmartButtonStateController.h @@ -0,0 +1,131 @@ +#pragma once + +#include "../SinricProRequest.h" +#include "../EventLimiter.h" +#include "../SinricProStrings.h" +#include "../SinricProNamespace.h" + +namespace SINRICPRO_NAMESPACE { + +// String constants for button states and actions +FSTR(BUTTONSTATE, state); // Button state key +FSTR(BUTTONSTATE, singlePress); // Single press state value +FSTR(BUTTONSTATE, doublePress); // Double press state value +FSTR(BUTTONSTATE, longPress); // Long press state value +FSTR(BUTTONSTATE, setSmartButtonState); // Set state action name + +// Callback type definitions for different button press events +using SmartButtonSinglePressCallback = std::function; +using SmartButtonDoublePressCallback = std::function; +using SmartButtonLongPressCallback = std::function; + +/** + * @brief Controller class for managing smart button state and interactions + * + * @tparam T The device type that this controller is attached to + */ +template +class SmartButtonStateController { +public: + /** + * @brief Construct a new Smart Button State Controller + * Automatically registers the request handler with the device + */ + SmartButtonStateController(); + + /** + * @brief Register callback for single press event from app + * @param cb Callback function to handle single press + */ + void onSinglePress(SmartButtonSinglePressCallback cb); + + /** + * @brief Register callback for double press event from app + * @param cb Callback function to handle double press + */ + void onDoublePress(SmartButtonDoublePressCallback cb); + + /** + * @brief Register callback for long press event from app + * @param cb Callback function to handle long press + */ + void onLongPress(SmartButtonLongPressCallback cb); + +protected: + /** + * @brief Handle incoming button state change requests + * @param request The incoming request to process + * @return true if request was handled successfully, false otherwise + */ + bool handleSmartButtonStateController(SinricProRequest &request); + +private: + SmartButtonSinglePressCallback smartButtonSinglePressCallback; + SmartButtonDoublePressCallback smartButtonDoublePressCallback; + SmartButtonLongPressCallback smartButtonLongPressCallback; + + /** + * returns true if states match, false otherwise + */ + inline bool isStateMatch(const SinricProRequest &request, const char* stateValue) { + return request.request_value[FSTR_BUTTONSTATE_state] == stateValue; + } +}; + +// Implementation + +template +SmartButtonStateController::SmartButtonStateController() { + T* device = static_cast(this); + device->registerRequestHandler( + std::bind(&SmartButtonStateController::handleSmartButtonStateController, + this, + std::placeholders::_1) + ); +} + +template +void SmartButtonStateController::onSinglePress(SmartButtonSinglePressCallback cb) { + smartButtonSinglePressCallback = cb; +} + +template +void SmartButtonStateController::onDoublePress(SmartButtonDoublePressCallback cb) { + smartButtonDoublePressCallback = cb; +} + +template +void SmartButtonStateController::onLongPress(SmartButtonLongPressCallback cb) { + smartButtonLongPressCallback = cb; +} + +template +bool SmartButtonStateController::handleSmartButtonStateController(SinricProRequest &request) { + // Only process setSmartButtonState actions + if (request.action != FSTR_BUTTONSTATE_setSmartButtonState) { + return false; + } + + T* device = static_cast(this); + bool success = false; + + // Handle single press + if (smartButtonSinglePressCallback && isStateMatch(request, FSTR_BUTTONSTATE_singlePress)) { + success = smartButtonSinglePressCallback(device->deviceId); + } + // Handle double press + else if (smartButtonDoublePressCallback && isStateMatch(request, FSTR_BUTTONSTATE_doublePress)) { + success = smartButtonDoublePressCallback(device->deviceId); + } + // Handle long press + else if (smartButtonLongPressCallback && isStateMatch(request, FSTR_BUTTONSTATE_longPress)) { + success = smartButtonLongPressCallback(device->deviceId); + } + + return success; +} + +} // namespace SINRICPRO_NAMESPACE + +template +using SmartButtonStateController = SINRICPRO_NAMESPACE::SmartButtonStateController; \ No newline at end of file From 4c48333f4b60ced50cbcf070bc3fd22e9a0898c6 Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Mon, 11 Nov 2024 23:22:21 +0700 Subject: [PATCH 2/6] feat: SmartButton --- src/SinricProVersion.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SinricProVersion.h b/src/SinricProVersion.h index 12758f4..59024ce 100644 --- a/src/SinricProVersion.h +++ b/src/SinricProVersion.h @@ -5,7 +5,7 @@ // Version Configuration #define SINRICPRO_VERSION_MAJOR 3 -#define SINRICPRO_VERSION_MINOR 2 +#define SINRICPRO_VERSION_MINOR 3 #define SINRICPRO_VERSION_REVISION 1 #define SINRICPRO_VERSION STR(SINRICPRO_VERSION_MAJOR) "." STR(SINRICPRO_VERSION_MINOR) "." STR(SINRICPRO_VERSION_REVISION) #define SINRICPRO_VERSION_STR "SinricPro (v" SINRICPRO_VERSION ")" From baa541bde068caadc2c6432adaf7d5aff2111306 Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Mon, 11 Nov 2024 23:29:26 +0700 Subject: [PATCH 3/6] feat: refactor to use a single callback --- src/Capabilities/SmartButtonStateController.h | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/Capabilities/SmartButtonStateController.h b/src/Capabilities/SmartButtonStateController.h index b26c038..7d55041 100644 --- a/src/Capabilities/SmartButtonStateController.h +++ b/src/Capabilities/SmartButtonStateController.h @@ -15,9 +15,7 @@ FSTR(BUTTONSTATE, longPress); // Long press state value FSTR(BUTTONSTATE, setSmartButtonState); // Set state action name // Callback type definitions for different button press events -using SmartButtonSinglePressCallback = std::function; -using SmartButtonDoublePressCallback = std::function; -using SmartButtonLongPressCallback = std::function; +using SmartButtonPressCallback = std::function; /** * @brief Controller class for managing smart button state and interactions @@ -37,19 +35,19 @@ class SmartButtonStateController { * @brief Register callback for single press event from app * @param cb Callback function to handle single press */ - void onSinglePress(SmartButtonSinglePressCallback cb); + void onSinglePress(SmartButtonPressCallback cb); /** * @brief Register callback for double press event from app * @param cb Callback function to handle double press */ - void onDoublePress(SmartButtonDoublePressCallback cb); + void onDoublePress(SmartButtonPressCallback cb); /** * @brief Register callback for long press event from app * @param cb Callback function to handle long press */ - void onLongPress(SmartButtonLongPressCallback cb); + void onLongPress(SmartButtonPressCallback cb); protected: /** @@ -60,9 +58,9 @@ class SmartButtonStateController { bool handleSmartButtonStateController(SinricProRequest &request); private: - SmartButtonSinglePressCallback smartButtonSinglePressCallback; - SmartButtonDoublePressCallback smartButtonDoublePressCallback; - SmartButtonLongPressCallback smartButtonLongPressCallback; + SmartButtonPressCallback smartButtonSinglePressCallback; + SmartButtonPressCallback smartButtonDoublePressCallback; + SmartButtonPressCallback smartButtonLongPressCallback; /** * returns true if states match, false otherwise @@ -85,17 +83,17 @@ SmartButtonStateController::SmartButtonStateController() { } template -void SmartButtonStateController::onSinglePress(SmartButtonSinglePressCallback cb) { +void SmartButtonStateController::onSinglePress(SmartButtonPressCallback cb) { smartButtonSinglePressCallback = cb; } template -void SmartButtonStateController::onDoublePress(SmartButtonDoublePressCallback cb) { +void SmartButtonStateController::onDoublePress(SmartButtonPressCallback cb) { smartButtonDoublePressCallback = cb; } template -void SmartButtonStateController::onLongPress(SmartButtonLongPressCallback cb) { +void SmartButtonStateController::onLongPress(SmartButtonPressCallback cb) { smartButtonLongPressCallback = cb; } From 330fbd5e7118f29dde6d16bccb24c310f747c67b Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Tue, 12 Nov 2024 10:13:22 +0700 Subject: [PATCH 4/6] feat: refactor to use onButtonPress --- src/Capabilities/SmartButtonStateController.h | 89 +++++++++---------- 1 file changed, 42 insertions(+), 47 deletions(-) diff --git a/src/Capabilities/SmartButtonStateController.h b/src/Capabilities/SmartButtonStateController.h index 7d55041..956566d 100644 --- a/src/Capabilities/SmartButtonStateController.h +++ b/src/Capabilities/SmartButtonStateController.h @@ -5,17 +5,25 @@ #include "../SinricProStrings.h" #include "../SinricProNamespace.h" +/** + * @brief Enum defining the different types of button press events + */ +enum class SmartButtonPressType { + SINGLE_PRESS, + DOUBLE_PRESS, + LONG_PRESS +}; + namespace SINRICPRO_NAMESPACE { -// String constants for button states and actions FSTR(BUTTONSTATE, state); // Button state key FSTR(BUTTONSTATE, singlePress); // Single press state value FSTR(BUTTONSTATE, doublePress); // Double press state value FSTR(BUTTONSTATE, longPress); // Long press state value FSTR(BUTTONSTATE, setSmartButtonState); // Set state action name -// Callback type definitions for different button press events -using SmartButtonPressCallback = std::function; +// Callback type definition for button press events +using SmartButtonPressCallback = std::function; /** * @brief Controller class for managing smart button state and interactions @@ -32,22 +40,10 @@ class SmartButtonStateController { SmartButtonStateController(); /** - * @brief Register callback for single press event from app - * @param cb Callback function to handle single press + * @brief Register callback for button press events + * @param cb Callback function to handle button press events */ - void onSinglePress(SmartButtonPressCallback cb); - - /** - * @brief Register callback for double press event from app - * @param cb Callback function to handle double press - */ - void onDoublePress(SmartButtonPressCallback cb); - - /** - * @brief Register callback for long press event from app - * @param cb Callback function to handle long press - */ - void onLongPress(SmartButtonPressCallback cb); + void onButtonPress(SmartButtonPressCallback cb); protected: /** @@ -58,9 +54,14 @@ class SmartButtonStateController { bool handleSmartButtonStateController(SinricProRequest &request); private: - SmartButtonPressCallback smartButtonSinglePressCallback; - SmartButtonPressCallback smartButtonDoublePressCallback; - SmartButtonPressCallback smartButtonLongPressCallback; + SmartButtonPressCallback buttonPressCallback; + + /** + * @brief Convert string state to SmartButtonPressType enum + * @param stateStr The state string from the request + * @return corresponding SmartButtonPressType enum value + */ + SmartButtonPressType getSmartButtonPressType(const String& stateStr); /** * returns true if states match, false otherwise @@ -70,8 +71,6 @@ class SmartButtonStateController { } }; -// Implementation - template SmartButtonStateController::SmartButtonStateController() { T* device = static_cast(this); @@ -83,44 +82,40 @@ SmartButtonStateController::SmartButtonStateController() { } template -void SmartButtonStateController::onSinglePress(SmartButtonPressCallback cb) { - smartButtonSinglePressCallback = cb; -} - -template -void SmartButtonStateController::onDoublePress(SmartButtonPressCallback cb) { - smartButtonDoublePressCallback = cb; +void SmartButtonStateController::onButtonPress(SmartButtonPressCallback cb) { + buttonPressCallback = cb; } template -void SmartButtonStateController::onLongPress(SmartButtonPressCallback cb) { - smartButtonLongPressCallback = cb; +SmartButtonPressType SmartButtonStateController::getSmartButtonPressType(const String& stateStr) { + if (stateStr == FSTR_BUTTONSTATE_singlePress) { + return SmartButtonPressType::SINGLE_PRESS; + } else if (stateStr == FSTR_BUTTONSTATE_doublePress) { + return SmartButtonPressType::DOUBLE_PRESS; + } else { + return SmartButtonPressType::LONG_PRESS; + } } template bool SmartButtonStateController::handleSmartButtonStateController(SinricProRequest &request) { // Only process setSmartButtonState actions - if (request.action != FSTR_BUTTONSTATE_setSmartButtonState) { + if (request.action != FSTR_BUTTONSTATE_setSmartButtonState || !buttonPressCallback) { return false; } T* device = static_cast(this); - bool success = false; - - // Handle single press - if (smartButtonSinglePressCallback && isStateMatch(request, FSTR_BUTTONSTATE_singlePress)) { - success = smartButtonSinglePressCallback(device->deviceId); - } - // Handle double press - else if (smartButtonDoublePressCallback && isStateMatch(request, FSTR_BUTTONSTATE_doublePress)) { - success = smartButtonDoublePressCallback(device->deviceId); - } - // Handle long press - else if (smartButtonLongPressCallback && isStateMatch(request, FSTR_BUTTONSTATE_longPress)) { - success = smartButtonLongPressCallback(device->deviceId); + String stateStr = request.request_value[FSTR_BUTTONSTATE_state]; + + // Only process valid button states + if (stateStr != FSTR_BUTTONSTATE_singlePress && + stateStr != FSTR_BUTTONSTATE_doublePress && + stateStr != FSTR_BUTTONSTATE_longPress) { + return false; } - return success; + SmartButtonPressType pressType = getSmartButtonPressType(stateStr); + return buttonPressCallback(device->deviceId, pressType); } } // namespace SINRICPRO_NAMESPACE From 49bfa0166359bdd4534e523d6ba9dd9df7b73d1f Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Tue, 12 Nov 2024 10:15:46 +0700 Subject: [PATCH 5/6] feat: smart button --- src/Capabilities/SmartButtonStateController.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/Capabilities/SmartButtonStateController.h b/src/Capabilities/SmartButtonStateController.h index 956566d..c0a6796 100644 --- a/src/Capabilities/SmartButtonStateController.h +++ b/src/Capabilities/SmartButtonStateController.h @@ -62,13 +62,6 @@ class SmartButtonStateController { * @return corresponding SmartButtonPressType enum value */ SmartButtonPressType getSmartButtonPressType(const String& stateStr); - - /** - * returns true if states match, false otherwise - */ - inline bool isStateMatch(const SinricProRequest &request, const char* stateValue) { - return request.request_value[FSTR_BUTTONSTATE_state] == stateValue; - } }; template From 0592d3e3608661421ec1415b8d5a4c257323dc65 Mon Sep 17 00:00:00 2001 From: Aruna Tennakoon Date: Tue, 12 Nov 2024 10:17:21 +0700 Subject: [PATCH 6/6] fix: comments --- src/Capabilities/SmartButtonStateController.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Capabilities/SmartButtonStateController.h b/src/Capabilities/SmartButtonStateController.h index c0a6796..147abe6 100644 --- a/src/Capabilities/SmartButtonStateController.h +++ b/src/Capabilities/SmartButtonStateController.h @@ -40,7 +40,7 @@ class SmartButtonStateController { SmartButtonStateController(); /** - * @brief Register callback for button press events + * @brief Register callback for button press events from the app * @param cb Callback function to handle button press events */ void onButtonPress(SmartButtonPressCallback cb);