Skip to content

Commit e335ea7

Browse files
authored
Merge pull request #437 from sinricpro/4.0-dev
feat: `sendSettingEvent` method has been added to SettingController.
2 parents e10c307 + 4f59844 commit e335ea7

6 files changed

Lines changed: 126 additions & 8 deletions

File tree

changelog.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
# Changelog
22

3+
## Version 4.1.0
4+
New:
5+
1. The `sendSettingEvent` method has been added to SettingController.
6+
7+
Example Usage:
8+
9+
```cpp
10+
// for device
11+
SinricProSwitch& mySwitch = SinricPro[SWITCH_ID];
12+
mySwitch.sendSettingEvent("brightness", 75); // Send int setting
13+
14+
// for module
15+
int rssi = WiFi.RSSI();
16+
SinricPro.sendSettingEvent('wifi_rssi', rssi);
17+
```
18+
19+
2. Validate APP_KEY, APP_SECRET, DEVICE_ID
20+
21+
322
## Version 4.0.0
423

524
- **BREAKING CHANGE**: Updated the callback signature in `SettingController.h` to use the `SettingValue` class instead of `String` for setting values.

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
}
1919
],
2020
"homepage": "https://sinric.pro",
21-
"version": "4.0.0",
21+
"version": "4.1.0",
2222
"frameworks": "arduino",
2323
"platforms": ["espressif8266", "espressif32", "raspberrypi"],
2424
"dependencies": [

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SinricPro
2-
version=4.0.0
2+
version=4.1.0
33
author=Boris Jaeger <sivar2311@gmail.com>
44
maintainer=Boris Jaeger <sivar2311@gmail.com>
55
sentence=Library for https://sinric.pro - simple way to connect your device to alexa

src/Capabilities/SettingController.h

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "../SinricProRequest.h"
66
#include "../SinricProStrings.h"
7+
#include "../EventLimiter.h"
78

89
#include "../SinricProNamespace.h"
910
namespace SINRICPRO_NAMESPACE {
@@ -24,16 +25,19 @@ class SettingController {
2425
public:
2526
SettingController();
2627
void onSetSetting(SetSettingCallback cb);
28+
bool sendSettingEvent(String settingId, SettingValue settingValue, String cause = FSTR_SINRICPRO_PHYSICAL_INTERACTION);
2729

2830
protected:
2931
bool handleSettingController(SinricProRequest &request);
3032

3133
private:
34+
EventLimiter event_limiter;
3235
SetSettingCallback setSettingCallback;
3336
};
3437

3538
template <typename T>
36-
SettingController<T>::SettingController() {
39+
SettingController<T>::SettingController()
40+
: event_limiter(EVENT_LIMIT_STATE) {
3741
T* device = static_cast<T*>(this);
3842
device->registerRequestHandler(std::bind(&SettingController<T>::handleSettingController, this, std::placeholders::_1));
3943
}
@@ -43,6 +47,39 @@ void SettingController<T>::onSetSetting(SetSettingCallback cb) {
4347
setSettingCallback = cb;
4448
}
4549

50+
/**
51+
* @brief Send `setSetting` event to SinricPro Server
52+
*
53+
* @param settingId `String` the setting identifier
54+
* @param settingValue `SettingValue` (int, float, bool, or String) the setting value
55+
* @param cause (optional) `String` reason why event is sent (default = `"PHYSICAL_INTERACTION"`)
56+
* @return the success of sending the event
57+
* @retval true event has been sent successfully
58+
* @retval false event has not been sent, maybe you sent too many events in a short distance of time
59+
**/
60+
template <typename T>
61+
bool SettingController<T>::sendSettingEvent(String settingId, SettingValue settingValue, String cause) {
62+
if (event_limiter) return false;
63+
T* device = static_cast<T*>(this);
64+
65+
JsonDocument eventMessage = device->prepareEvent(FSTR_SETTING_setSetting, cause.c_str());
66+
JsonObject event_value = eventMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
67+
eventMessage[FSTR_SINRICPRO_scope] = FSTR_SINRICPRO_device;
68+
event_value[FSTR_SETTING_id] = settingId;
69+
70+
if (std::holds_alternative<int>(settingValue)) {
71+
event_value[FSTR_SETTING_value] = std::get<int>(settingValue);
72+
} else if (std::holds_alternative<float>(settingValue)) {
73+
event_value[FSTR_SETTING_value] = std::get<float>(settingValue);
74+
} else if (std::holds_alternative<bool>(settingValue)) {
75+
event_value[FSTR_SETTING_value] = std::get<bool>(settingValue);
76+
} else if (std::holds_alternative<String>(settingValue)) {
77+
event_value[FSTR_SETTING_value] = std::get<String>(settingValue);
78+
}
79+
80+
return device->sendEvent(eventMessage);
81+
}
82+
4683
template <typename T>
4784
bool SettingController<T>::handleSettingController(SinricProRequest &request) {
4885
T* device = static_cast<T*>(this);

src/SinricPro.h

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "SinricProUDP.h"
1919
#include "SinricProWebsocket.h"
2020
#include "Timestamp.h"
21+
#include "EventLimiter.h"
2122
namespace SINRICPRO_NAMESPACE {
2223

2324
/**
@@ -108,6 +109,7 @@ class SinricProClass : public SinricProInterface {
108109
void onOTAUpdate(OTAUpdateCallbackHandler cb);
109110
void onSetSetting(SetSettingCallbackHandler cb);
110111
void onReportHealth(ReportHealthCallbackHandler cb);
112+
bool sendSettingEvent(String settingId, SettingValue settingValue, String cause = FSTR_SINRICPRO_PHYSICAL_INTERACTION);
111113

112114
protected:
113115
template <typename DeviceType>
@@ -162,6 +164,7 @@ class SinricProClass : public SinricProInterface {
162164
String responseMessageStr = "";
163165

164166
SinricProModuleCommandHandler _moduleCommandHandler;
167+
EventLimiter _settingEventLimiter{EVENT_LIMIT_STATE};
165168
};
166169

167170
class SinricProClass::Proxy {
@@ -225,12 +228,27 @@ DeviceType& SinricProClass::getDeviceInstance(String deviceId) {
225228
**/
226229
void SinricProClass::begin(String appKey, String appSecret, String serverURL) {
227230
bool success = true;
228-
if (!appKey.length()) {
229-
DEBUG_SINRIC("[SinricPro:begin()]: App-Key \"%s\" is invalid!! Please check your app-key!! SinricPro will not work!\r\n", appKey.c_str());
231+
232+
// Validate APP_KEY
233+
// - Must be 36 characters
234+
// - UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
235+
if (appKey.length() != 36) {
236+
Serial.printf("[SinricPro:begin()]: Invalid App Key '%s' detected (Length: %d; Expected: 36). Initialization aborted! Please check your SinricPro credentials.\r\n", appKey.c_str(), appKey.length());
237+
success = false;
238+
} else if (appKey.charAt(8) != '-' || appKey.charAt(13) != '-' || appKey.charAt(18) != '-' || appKey.charAt(23) != '-') {
239+
Serial.printf("[SinricPro:begin()]: App Key '%s' is in an invalid format. Initialization aborted!\r\n", appKey.c_str());
230240
success = false;
231241
}
232-
if (!appSecret.length()) {
233-
DEBUG_SINRIC("[SinricPro:begin()]: App-Secret \"%s\" is invalid!! Please check your app-secret!! SinricPro will not work!\r\n", appSecret.c_str());
242+
243+
// Validate APP_SECRET (73 characters)
244+
// - Must be 73 characters
245+
// - Double UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
246+
if (appSecret.length() != 73) {
247+
Serial.printf("[SinricPro:begin()]: Invalid App Secret '%s' detected (Length: %d; Expected: 73). Initialization aborted! Please check your SinricPro credentials.\r\n", appSecret.c_str(), appSecret.length());
248+
success = false;
249+
} else if (appSecret.charAt(8) != '-' || appSecret.charAt(13) != '-' || appSecret.charAt(18) != '-' || appSecret.charAt(23) != '-' ||
250+
appSecret.charAt(36) != '-' || appSecret.charAt(45) != '-' || appSecret.charAt(50) != '-' || appSecret.charAt(55) != '-' || appSecret.charAt(60) != '-') {
251+
Serial.printf("[SinricPro:begin()]: App Secret '%s' is in an invalid format. Initialization aborted!\r\n", appSecret.c_str());
234252
success = false;
235253
}
236254

@@ -248,6 +266,14 @@ void SinricProClass::begin(String appKey, String appSecret, String serverURL) {
248266

249267
template <typename DeviceType>
250268
DeviceType& SinricProClass::add(String deviceId) {
269+
// Validate DEVICE_ID
270+
// - Must be 24 characters
271+
// - Hexadecimal only (0-9, a-f, A-F)
272+
// - Format: 695b4624f6e5944047661b8a
273+
if (deviceId.length() != 24) {
274+
Serial.printf("[SinricPro:add()]: Device Id \"%s\" is invalid (wrong length: expected 24, got %d)!! Please check your device-id!!\r\n", deviceId.c_str(), deviceId.length());
275+
}
276+
251277
DeviceType* newDevice = new DeviceType(deviceId);
252278
DEBUG_SINRIC("[SinricPro:add()]: Adding device with id \"%s\".\r\n", deviceId.c_str());
253279
newDevice->begin(this);
@@ -564,6 +590,42 @@ void SinricProClass::onReportHealth(ReportHealthCallbackHandler cb) {
564590
_moduleCommandHandler.onReportHealth(cb);
565591
}
566592

593+
/**
594+
* @brief Send `setSetting` event to SinricPro Server at module level
595+
*
596+
* @param settingId `String` the setting identifier
597+
* @param settingValue `SettingValue` (int, float, bool, or String) the setting value
598+
* @param cause (optional) `String` reason why event is sent (default = `"PHYSICAL_INTERACTION"`)
599+
* @return the success of sending the event
600+
* @retval true event has been sent successfully
601+
* @retval false event has not been sent, maybe you sent too many events in a short distance of time
602+
**/
603+
bool SinricProClass::sendSettingEvent(String settingId, SettingValue settingValue, String cause) {
604+
if (_settingEventLimiter) return false;
605+
606+
JsonDocument eventMessage = prepareEvent("", FSTR_SETTING_setSetting, cause.c_str());
607+
JsonObject payload = eventMessage[FSTR_SINRICPRO_payload];
608+
609+
payload.remove(FSTR_SINRICPRO_deviceId);
610+
payload[FSTR_SINRICPRO_scope] = FSTR_SINRICPRO_module;
611+
612+
JsonObject event_value = payload[FSTR_SINRICPRO_value];
613+
event_value[FSTR_SETTING_id] = settingId;
614+
615+
if (std::holds_alternative<int>(settingValue)) {
616+
event_value[FSTR_SETTING_value] = std::get<int>(settingValue);
617+
} else if (std::holds_alternative<float>(settingValue)) {
618+
event_value[FSTR_SETTING_value] = std::get<float>(settingValue);
619+
} else if (std::holds_alternative<bool>(settingValue)) {
620+
event_value[FSTR_SETTING_value] = std::get<bool>(settingValue);
621+
} else if (std::holds_alternative<String>(settingValue)) {
622+
event_value[FSTR_SETTING_value] = std::get<String>(settingValue);
623+
}
624+
625+
sendMessage(eventMessage);
626+
return true;
627+
}
628+
567629
/**
568630
* @brief Set callback function for websocket connected event
569631
*

src/SinricProVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
// Version Configuration
77
#define SINRICPRO_VERSION_MAJOR 4
8-
#define SINRICPRO_VERSION_MINOR 0
8+
#define SINRICPRO_VERSION_MINOR 1
99
#define SINRICPRO_VERSION_REVISION 0
1010
#define SINRICPRO_VERSION STR(SINRICPRO_VERSION_MAJOR) "." STR(SINRICPRO_VERSION_MINOR) "." STR(SINRICPRO_VERSION_REVISION)
1111
#define SINRICPRO_VERSION_STR "SinricPro (v" SINRICPRO_VERSION ")"

0 commit comments

Comments
 (0)