1
+ #pragma once
2
+
3
+ #include " ../SinricProRequest.h"
4
+ #include " ../EventLimiter.h"
5
+ #include " ../SinricProStrings.h"
6
+
7
+ #include " ../SinricProNamespace.h"
8
+ namespace SINRICPRO_NAMESPACE {
9
+
10
+ FSTR (OPEN_CLOSE, openPercent); // "openPercent"
11
+ FSTR (OPEN_CLOSE, openRelativePercent); // "openRelativePercent"
12
+ FSTR (OPEN_CLOSE, openDirection); // "openDirection"
13
+ FSTR (OPEN_CLOSE, setOpenClose); // "setOpenClose"
14
+ FSTR (OPEN_CLOSE, adjustOpenClose); // "adjustOpenClose"
15
+
16
+
17
+ /* *
18
+ * @brief Callback definition for onOpenClose callback
19
+ *
20
+ * Gets called when device receives a `setOpenClose` request
21
+ * @param[in] deviceId String containing the ID of device
22
+ * @param[in,out] openPercent Integer percentage (0-100) of how open the device should be set (0 = closed, 100 = fully open)
23
+ * @return Success status of the request
24
+ * @retval true Request handled successfully
25
+ * @retval false Request handling failed
26
+ *
27
+ * @section OpenCloseCallback Example-Code
28
+ * @snippet callbacks.cpp onSetOpenClose
29
+ **/
30
+ using OpenCloseCallback = std::function<bool (const String &, int &)>;
31
+
32
+ /* *
33
+ * @brief Callback definition for onAdjustOpenClose callback
34
+ *
35
+ * Gets called when device receives an `adjustOpenClose` request
36
+ * @param[in] deviceId String containing the ID of device
37
+ * @param[in,out] openRelativePercent Integer value representing the relative percentage change to apply
38
+ * On output, should contain the absolute percentage value the device has been set to
39
+ * @return Success status of the request
40
+ * @retval true Request handled successfully
41
+ * @retval false Request handling failed
42
+ *
43
+ * @section AdjustOpenCloseCallback Example-Code
44
+ * @snippet callbacks.cpp onAdjustOpenClose
45
+ **/
46
+ using AdjustOpenCloseCallback = std::function<bool (const String &, int &)>;
47
+
48
+ /* *
49
+ * @brief Callback definition for onDirectionOpenClose callback
50
+ *
51
+ * Gets called when device receives a `setOpenClose` request with direction information
52
+ * @param[in] deviceId String containing the ID of device
53
+ * @param[in] openDirection String direction in which to open: `UP`, `DOWN`, `LEFT`, `RIGHT`, `IN`, `OUT`
54
+ * @param[in,out] openPercent Integer percentage (0-100) of how open the device should be set
55
+ * @return Success status of the request
56
+ * @retval true Request handled successfully
57
+ * @retval false Request handling failed
58
+ *
59
+ * @section DirectionOpenCloseCallback Example-Code
60
+ * @snippet callbacks.cpp onDirectionOpenClose
61
+ **/
62
+ using DirectionOpenCloseCallback = std::function<bool (const String &, const String &, int &)>;
63
+
64
+ /* *
65
+ * @brief Callback definition for onAdjustDirectionOpenClose callback
66
+ *
67
+ * Gets called when device receives an `adjustOpenClose` request with direction information
68
+ * @param[in] deviceId String containing the ID of device
69
+ * @param[in] openDirection String direction in which to open: `UP`, `DOWN`, `LEFT`, `RIGHT`, `IN`, `OUT`
70
+ * @param[in,out] openRelativePercent Integer representing relative percentage change to apply
71
+ * On output, should contain the absolute percentage value the device has been set to
72
+ * @return Success status of the request
73
+ * @retval true Request handled successfully
74
+ * @retval false Request handling failed
75
+ *
76
+ * @section AdjustDirectionOpenCloseCallback Example-Code
77
+ * @snippet callbacks.cpp onAdjustDirectionOpenClose
78
+ **/
79
+ using AdjustDirectionOpenCloseCallback = std::function<bool (const String &, const String &, int &)>;
80
+
81
+ /* *
82
+ * @brief Controller class for devices with open/close functionality
83
+ * @ingroup Capabilities
84
+ * This controller handles open/close operations for devices that can be opened or closed by percentage and may supports multiple directions.
85
+ *
86
+ * @tparam T Device type that implements this controller
87
+ */
88
+ template <typename T>
89
+ class OpenCloseController {
90
+ public:
91
+ OpenCloseController ();
92
+
93
+ /* *
94
+ * @brief Set callback function for simple open/close operations
95
+ *
96
+ * @param cb Function pointer to a `OpenCloseCallback` function
97
+ * @return void
98
+ * @see OpenCloseCallback
99
+ **/
100
+ void onOpenClose (OpenCloseCallback cb);
101
+
102
+ /* *
103
+ * @brief Set callback function for directional open/close operations
104
+ *
105
+ * @param cb Function pointer to a `DirectionOpenCloseCallback` function
106
+ * @return void
107
+ * @see DirectionOpenCloseCallback
108
+ **/
109
+ void onDirectionOpenClose (DirectionOpenCloseCallback cb);
110
+
111
+ /* *
112
+ * @brief Set callback function for relative adjustments to open/close status
113
+ *
114
+ * @param cb Function pointer to a `AdjustOpenCloseCallback` function
115
+ * @return void
116
+ * @see AdjustOpenCloseCallback
117
+ **/
118
+ void onAdjustOpenClose (AdjustOpenCloseCallback cb);
119
+
120
+ /* *
121
+ * @brief Set callback function for directional relative adjustments
122
+ *
123
+ * @param cb Function pointer to a `AdjustDirectionOpenCloseCallback` function
124
+ * @return void
125
+ * @see AdjustDirectionOpenCloseCallback
126
+ **/
127
+ void onAdjustDirectionOpenClose (AdjustDirectionOpenCloseCallback cb);
128
+
129
+ /* *
130
+ * @brief Send an event to update the open/close status
131
+ *
132
+ * @param openPercent Current open percentage (0-100)
133
+ * @param cause Cause of the event (default: physical interaction)
134
+ * @return bool Whether the event was sent successfully
135
+ **/
136
+ bool sendOpenCloseEvent (int openPercent, String cause = FSTR_SINRICPRO_PHYSICAL_INTERACTION);
137
+
138
+ /* *
139
+ * @brief Send an event to update the open/close status with direction
140
+ *
141
+ * @param openDirection Direction of opening (UP, DOWN, LEFT, RIGHT, IN, OUT)
142
+ * @param openPercent Current open percentage (0-100)
143
+ * @param cause Cause of the event (default: physical interaction)
144
+ * @return bool Whether the event was sent successfully
145
+ **/
146
+ bool sendOpenCloseEvent (String openDirection, int openPercent, String cause = FSTR_SINRICPRO_PHYSICAL_INTERACTION);
147
+
148
+ protected:
149
+ /* *
150
+ * @brief Handle incoming open/close control requests
151
+ *
152
+ * @param request The incoming request to process
153
+ * @return bool Whether the request was handled successfully
154
+ **/
155
+ bool handleOpenCloseController (SinricProRequest &request);
156
+
157
+ private:
158
+ EventLimiter event_limiter;
159
+ DirectionOpenCloseCallback directionOpenCloseCallback;
160
+ OpenCloseCallback openCloseCallback;
161
+ AdjustOpenCloseCallback adjustOpenCloseCallback;
162
+ AdjustDirectionOpenCloseCallback adjustDirectionOpenCloseCallback;
163
+ };
164
+
165
+ template <typename T>
166
+ OpenCloseController<T>::OpenCloseController()
167
+ :event_limiter(EVENT_LIMIT_STATE) {
168
+ T* device = static_cast <T*>(this );
169
+ device->registerRequestHandler (std::bind (&OpenCloseController<T>::handleOpenCloseController, this , std::placeholders::_1));
170
+ }
171
+
172
+ template <typename T>
173
+ void OpenCloseController<T>::onOpenClose(OpenCloseCallback cb) { openCloseCallback = cb; }
174
+
175
+ template <typename T>
176
+ void OpenCloseController<T>::onDirectionOpenClose(DirectionOpenCloseCallback cb) { directionOpenCloseCallback = cb; }
177
+
178
+ template <typename T>
179
+ void OpenCloseController<T>::onAdjustOpenClose(AdjustOpenCloseCallback cb) { adjustOpenCloseCallback = cb; }
180
+
181
+ template <typename T>
182
+ void OpenCloseController<T>::onAdjustDirectionOpenClose(AdjustDirectionOpenCloseCallback cb) { adjustDirectionOpenCloseCallback = cb; }
183
+
184
+ /* *
185
+ * @brief Send an event to update open/close status with open direction and precent and information
186
+ *
187
+ * Sends the current open/close status with direction to the Sinric Pro cloud.
188
+ * The event will only be sent if the event rate limiter allows it.
189
+ *
190
+ * @param openDirection Direction in which the device is opening
191
+ * @param openPercent Current open percentage (0-100)
192
+ * @param cause Reason for the state change (default: physical interaction)
193
+ * @return bool Whether the event was sent successfully
194
+ */
195
+ template <typename T>
196
+ bool OpenCloseController<T>::sendOpenCloseEvent(String openDirection, int openPercent, String cause) {
197
+ if (event_limiter) return false ;
198
+ T* device = static_cast <T*>(this );
199
+
200
+ JsonDocument eventMessage = device->prepareEvent (FSTR_OPEN_CLOSE_setOpenClose, cause.c_str ());
201
+ JsonObject event_value = eventMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
202
+ event_value[FSTR_OPEN_CLOSE_openDirection] = openDirection;
203
+ event_value[FSTR_OPEN_CLOSE_openPercent] = openPercent;
204
+
205
+ return device->sendEvent (eventMessage);
206
+ }
207
+
208
+ /* *
209
+ * @brief Send an event to update open/close status
210
+ *
211
+ * Sends the current open/close percentage to the Sinric Pro cloud.
212
+ * The event will only be sent if the event rate limiter allows it.
213
+ *
214
+ * @param openPercent Current open percentage (0-100)
215
+ * @param cause Reason for the state change (default: physical interaction)
216
+ * @return bool Whether the event was sent successfully
217
+ */
218
+ template <typename T>
219
+ bool OpenCloseController<T>::sendOpenCloseEvent(int openPercent, String cause) {
220
+ if (event_limiter) return false ;
221
+ T* device = static_cast <T*>(this );
222
+
223
+ JsonDocument eventMessage = device->prepareEvent (FSTR_OPEN_CLOSE_setOpenClose, cause.c_str ());
224
+ JsonObject event_value = eventMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
225
+ event_value[FSTR_OPEN_CLOSE_openPercent] = openPercent;
226
+
227
+ return device->sendEvent (eventMessage);
228
+ }
229
+
230
+ /* *
231
+ * @brief Handle incoming open/close requests
232
+ *
233
+ * Processes both setOpenClose and adjustOpenClose requests with or without direction information.
234
+ * Delegates to the appropriate callback function based on the request type and parameters.
235
+ *
236
+ * @param request The incoming request containing action and parameters
237
+ * @return bool Whether the request was handled successfully
238
+ */
239
+ template <typename T>
240
+ bool OpenCloseController<T>::handleOpenCloseController(SinricProRequest &request) {
241
+ T* device = static_cast <T*>(this );
242
+
243
+ bool success = false ;
244
+
245
+ if (request.action == FSTR_OPEN_CLOSE_setOpenClose) {
246
+ bool hasOpenDirection = !request.request_value [FSTR_OPEN_CLOSE_openDirection].isNull ();
247
+ int openPercent = request.request_value [FSTR_OPEN_CLOSE_openPercent];
248
+
249
+ if (hasOpenDirection && directionOpenCloseCallback) {
250
+ String openDirection = request.request_value [FSTR_OPEN_CLOSE_openDirection];
251
+ success = directionOpenCloseCallback (device->deviceId , openDirection, openPercent);
252
+ request.response_value [FSTR_OPEN_CLOSE_openDirection] = openDirection;
253
+ request.response_value [FSTR_OPEN_CLOSE_openPercent] = openPercent;
254
+ } else if (!hasOpenDirection && openCloseCallback) {
255
+ success = openCloseCallback (device->deviceId , openPercent);
256
+ request.response_value [FSTR_OPEN_CLOSE_openPercent] = openPercent;
257
+ }
258
+
259
+ return success;
260
+ }
261
+
262
+ if (request.action == FSTR_OPEN_CLOSE_adjustOpenClose) {
263
+ bool hasOpenDirection = !request.request_value [FSTR_OPEN_CLOSE_openDirection].isNull ();
264
+ int openRelativePercent = request.request_value [FSTR_OPEN_CLOSE_openRelativePercent];
265
+
266
+ if (hasOpenDirection && adjustDirectionOpenCloseCallback) {
267
+ String openDirection = request.request_value [FSTR_OPEN_CLOSE_openDirection];
268
+ success = adjustDirectionOpenCloseCallback (device->deviceId , openDirection, openRelativePercent);
269
+ request.response_value [FSTR_OPEN_CLOSE_openDirection] = openDirection;
270
+ request.response_value [FSTR_OPEN_CLOSE_openPercent] = openRelativePercent;
271
+ } else if (!hasOpenDirection && adjustOpenCloseCallback) {
272
+ success = adjustOpenCloseCallback (device->deviceId , openRelativePercent);
273
+ request.response_value [FSTR_OPEN_CLOSE_openPercent] = openRelativePercent;
274
+ }
275
+
276
+ return success;
277
+ }
278
+
279
+ return false ;
280
+ }
281
+
282
+ } // SINRICPRO_NAMESPACE
283
+
284
+ template <typename T>
285
+ using OpenCloseController = SINRICPRO_NAMESPACE::OpenCloseController<T>;
0 commit comments