Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: SmartButton #405

Merged
merged 6 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Changelog

## Version 3.3.1
- Support SmartButton.

## Version 3.2.1
- Fixed Arduino Lint errors
- LICENSE.txt added
Expand Down
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"maintainer": true
}
],
"version": "3.2.1",
"version": "3.3.1",
"frameworks": "arduino",
"platforms": [
"espressif8266",
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SinricPro
version=3.2.1
version=3.3.1
author=Boris Jaeger <[email protected]>
maintainer=Boris Jaeger <[email protected]>
sentence=Library for https://sinric.pro - simple way to connect your device to alexa
Expand Down
131 changes: 131 additions & 0 deletions src/Capabilities/SmartButtonStateController.h
kakopappa marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -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<bool(const String &)>;
using SmartButtonDoublePressCallback = std::function<bool(const String &)>;
using SmartButtonLongPressCallback = std::function<bool(const String &)>;

/**
* @brief Controller class for managing smart button state and interactions
*
* @tparam T The device type that this controller is attached to
*/
template <typename T>
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 <typename T>
SmartButtonStateController<T>::SmartButtonStateController() {
T* device = static_cast<T*>(this);
device->registerRequestHandler(
std::bind(&SmartButtonStateController<T>::handleSmartButtonStateController,
this,
std::placeholders::_1)
);
}

template <typename T>
void SmartButtonStateController<T>::onSinglePress(SmartButtonSinglePressCallback cb) {
smartButtonSinglePressCallback = cb;
}

template <typename T>
void SmartButtonStateController<T>::onDoublePress(SmartButtonDoublePressCallback cb) {
smartButtonDoublePressCallback = cb;
}

template <typename T>
void SmartButtonStateController<T>::onLongPress(SmartButtonLongPressCallback cb) {
smartButtonLongPressCallback = cb;
}

template <typename T>
bool SmartButtonStateController<T>::handleSmartButtonStateController(SinricProRequest &request) {
// Only process setSmartButtonState actions
if (request.action != FSTR_BUTTONSTATE_setSmartButtonState) {
return false;
}

T* device = static_cast<T*>(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 <typename T>
using SmartButtonStateController = SINRICPRO_NAMESPACE::SmartButtonStateController<T>;
Loading