Skip to content

Commit 7237966

Browse files
authored
Merge pull request #409 from sivar2311/master
3.4.0 branch
2 parents 2ad7bff + 444d0b4 commit 7237966

15 files changed

+198
-63
lines changed

changelog.md

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

3+
## Version 3.4.0
4+
New:
5+
- Support Image upload on camera devices
6+
7+
Fixed:
8+
- Removed calls to `containsKey` - deprecated since ArduinoJSON 7.2
9+
- Missing includes
10+
311
## Version 3.3.1
412
- Support SmartButton.
513

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"maintainer": true
1414
}
1515
],
16-
"version": "3.3.1",
16+
"version": "3.4.0",
1717
"frameworks": "arduino",
1818
"platforms": [
1919
"espressif8266",

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=3.3.1
2+
version=3.4.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
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#pragma once
2+
3+
#include "../EventLimiter.h"
4+
#include "../SinricProNamespace.h"
5+
#include "../SinricProRequest.h"
6+
#include "../SinricProStrings.h"
7+
#include <HTTPClient.h>
8+
#include <WiFiClientSecure.h>
9+
10+
namespace SINRICPRO_NAMESPACE {
11+
12+
FSTR(CAMERA, getSnapshot); // "getSnapshot"
13+
14+
using SnapshotCallback = std::function<bool(const String &)>;
15+
16+
template <typename T>
17+
class CameraController {
18+
public:
19+
CameraController();
20+
void onSnapshot(SnapshotCallback cb);
21+
int sendSnapshot(uint8_t* buffer, size_t len);
22+
23+
protected:
24+
bool handleCameraController(SinricProRequest &request);
25+
26+
private:
27+
SnapshotCallback getSnapshotCallback = nullptr;
28+
};
29+
30+
template <typename T>
31+
CameraController<T>::CameraController() {
32+
T *device = static_cast<T *>(this);
33+
device->registerRequestHandler(std::bind(&CameraController<T>::handleCameraController, this, std::placeholders::_1));
34+
}
35+
36+
template <typename T>
37+
void CameraController<T>::onSnapshot(SnapshotCallback cb) {
38+
getSnapshotCallback = cb;
39+
}
40+
41+
template <typename T>
42+
bool CameraController<T>::handleCameraController(SinricProRequest &request) {
43+
T *device = static_cast<T *>(this);
44+
45+
bool success = false;
46+
47+
if (request.action == FSTR_CAMERA_getSnapshot) {
48+
if (getSnapshotCallback) {
49+
success = getSnapshotCallback(device->deviceId);
50+
}
51+
}
52+
53+
return success;
54+
}
55+
56+
template <typename T>
57+
int CameraController<T>::sendSnapshot(uint8_t* buffer, size_t len) {
58+
T *device = static_cast<T *>(this);
59+
60+
if (!buffer) return -1;
61+
62+
WiFiClientSecure client;
63+
client.setInsecure();
64+
65+
HTTPClient http;
66+
if (!http.begin(client, SINRICPRO_CAMERA_URL, 443, SINRICPRO_CAMERA_PATH, true)) return -1;
67+
68+
const String& deviceId = device->getDeviceId();
69+
String timestamp = String(device->getTimestamp());
70+
String signature = device->sign(deviceId+timestamp);
71+
72+
http.addHeader(FSTR_SINRICPRO_deviceId, deviceId);
73+
http.addHeader(FSTR_SINRICPRO_timestamp, timestamp);
74+
http.addHeader(FSTR_SINRICPRO_signature, signature);
75+
76+
int resCode = http.POST(buffer, len);
77+
http.end();
78+
79+
return resCode;
80+
}
81+
82+
} // namespace SINRICPRO_NAMESPACE

src/Capabilities/ChannelController.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,13 @@ bool ChannelController<T>::handleChannelController(SinricProRequest &request) {
157157

158158
if (request.action == FSTR_CHANNEL_changeChannel) {
159159

160-
if (changeChannelCallback && request.request_value[FSTR_CHANNEL_channel].containsKey(FSTR_CHANNEL_name)) {
160+
if (changeChannelCallback && request.request_value[FSTR_CHANNEL_channel][FSTR_CHANNEL_name].is<String>()) {
161161
String channelName = request.request_value[FSTR_CHANNEL_channel][FSTR_CHANNEL_name] | "";
162162
success = changeChannelCallback(device->deviceId, channelName);
163163
request.response_value[FSTR_CHANNEL_channel][FSTR_CHANNEL_name] = channelName;
164164
}
165165

166-
if (changeChannelNumberCallback && request.request_value[FSTR_CHANNEL_channel].containsKey(FSTR_CHANNEL_number)) {
166+
if (changeChannelNumberCallback && request.request_value[FSTR_CHANNEL_channel][FSTR_CHANNEL_number].is<String>()) {
167167
String channelName("");
168168
int channelNumber = request.request_value[FSTR_CHANNEL_channel][FSTR_CHANNEL_number];
169169
success = changeChannelNumberCallback(device->deviceId, channelNumber, channelName);

src/Capabilities/ThermostatController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ bool ThermostatController<T>::handleThermostatController(SinricProRequest &reque
181181

182182
if (request.action == FSTR_THERMOSTAT_targetTemperature && targetTemperatureCallback) {
183183
float temperature;
184-
if (request.request_value.containsKey(FSTR_THERMOSTAT_temperature)) {
184+
if (request.request_value[FSTR_THERMOSTAT_temperature].is<Float>()) {
185185
temperature = request.request_value[FSTR_THERMOSTAT_temperature];
186186
} else {
187187
temperature = 1;

src/SinricPro.h

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
#include "SinricProDeviceInterface.h"
1111
#include "SinricProInterface.h"
1212
#include "SinricProMessageid.h"
13+
#include "SinricProModuleCommandHandler.h"
1314
#include "SinricProNamespace.h"
1415
#include "SinricProQueue.h"
1516
#include "SinricProSignature.h"
1617
#include "SinricProStrings.h"
1718
#include "SinricProUDP.h"
1819
#include "SinricProWebsocket.h"
1920
#include "Timestamp.h"
20-
#include "SinricProModuleCommandHandler.h"
2121
namespace SINRICPRO_NAMESPACE {
2222

2323
/**
@@ -57,7 +57,7 @@ using OTAUpdateCallbackHandler = std::function<bool(const String& url, int major
5757
* @brief Function signature for setting a module setting.
5858
*
5959
* This callback is used to set a value for a specific setting identified by its ID.
60-
*
60+
*
6161
* @param id The unique identifier of the setting to be set.
6262
* @param value The new value to be assigned to the setting.
6363
* @return bool Returns true if the setting was successfully updated, false otherwise.
@@ -93,20 +93,21 @@ class SinricProClass : public SinricProInterface {
9393
class Proxy;
9494

9595
public:
96-
void begin(String appKey, String appSecret, String serverURL = SINRICPRO_SERVER_URL);
97-
void handle();
98-
void stop();
99-
bool isConnected();
100-
void onConnected(ConnectedCallbackHandler cb);
101-
void onDisconnected(DisconnectedCallbackHandler cb);
102-
void onPong(PongCallback cb);
103-
void restoreDeviceStates(bool flag);
104-
void setResponseMessage(String&& message);
105-
unsigned long getTimestamp() override;
106-
Proxy operator[](const String deviceId);
107-
void onOTAUpdate(OTAUpdateCallbackHandler cb);
108-
void onSetSetting(SetSettingCallbackHandler cb);
109-
void onReportHealth(ReportHealthCallbackHandler cb);
96+
void begin(String appKey, String appSecret, String serverURL = SINRICPRO_SERVER_URL);
97+
void handle();
98+
void stop();
99+
bool isConnected();
100+
void onConnected(ConnectedCallbackHandler cb);
101+
void onDisconnected(DisconnectedCallbackHandler cb);
102+
void onPong(PongCallback cb);
103+
void restoreDeviceStates(bool flag);
104+
void setResponseMessage(String&& message);
105+
unsigned long getTimestamp() override;
106+
virtual String sign(const String& message);
107+
Proxy operator[](const String deviceId);
108+
void onOTAUpdate(OTAUpdateCallbackHandler cb);
109+
void onSetSetting(SetSettingCallbackHandler cb);
110+
void onReportHealth(ReportHealthCallbackHandler cb);
110111

111112
protected:
112113
template <typename DeviceType>
@@ -117,7 +118,7 @@ class SinricProClass : public SinricProInterface {
117118

118119
JsonDocument prepareResponse(JsonDocument& requestMessage);
119120
JsonDocument prepareEvent(String deviceId, const char* action, const char* cause) override;
120-
void sendMessage(JsonDocument& jsonMessage) override;
121+
void sendMessage(JsonDocument& jsonMessage) override;
121122

122123
private:
123124
void handleReceiveQueue();
@@ -301,7 +302,7 @@ void SinricProClass::handle() {
301302

302303
JsonDocument SinricProClass::prepareRequest(String deviceId, const char* action) {
303304
JsonDocument requestMessage;
304-
JsonObject header = requestMessage[FSTR_SINRICPRO_header].to<JsonObject>();
305+
JsonObject header = requestMessage[FSTR_SINRICPRO_header].to<JsonObject>();
305306
header[FSTR_SINRICPRO_payloadVersion] = 2;
306307
header[FSTR_SINRICPRO_signatureVersion] = 1;
307308

@@ -332,20 +333,20 @@ void SinricProClass::handleModuleRequest(JsonDocument& requestMessage, interface
332333
#endif
333334

334335
JsonDocument responseMessage = prepareResponse(requestMessage);
335-
336-
String action = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_action] | "";
337-
JsonObject request_value = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
338-
JsonObject response_value = responseMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
339-
SinricProRequest request{ action, "", request_value, response_value};
336+
337+
String action = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_action] | "";
338+
JsonObject request_value = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
339+
JsonObject response_value = responseMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_value];
340+
SinricProRequest request{action, "", request_value, response_value};
340341

341342
bool success = _moduleCommandHandler.handleRequest(request);
342-
343+
343344
responseMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_success] = success;
344345
responseMessage[FSTR_SINRICPRO_payload].remove(FSTR_SINRICPRO_deviceId);
345346
if (!success) {
346347
if (responseMessageStr.length() > 0) {
347348
responseMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_message] = responseMessageStr;
348-
responseMessageStr = "";
349+
responseMessageStr = "";
349350
} else {
350351
responseMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_message] = "Module did not handle \"" + action + "\"";
351352
}
@@ -424,13 +425,13 @@ void SinricProClass::handleReceiveQueue() {
424425
DEBUG_SINRIC("[SinricPro.handleReceiveQueue()]: Signature is valid. Processing message...\r\n");
425426
extractTimestamp(jsonMessage);
426427
if (messageType == FSTR_SINRICPRO_response) handleResponse(jsonMessage);
427-
if (messageType == FSTR_SINRICPRO_request) {
428+
if (messageType == FSTR_SINRICPRO_request) {
428429
String scope = jsonMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_scope] | FSTR_SINRICPRO_device;
429430
if (strcmp(FSTR_SINRICPRO_module, scope.c_str()) == 0) {
430431
handleModuleRequest(jsonMessage, rawMessage->getInterface());
431432
} else {
432433
handleDeviceRequest(jsonMessage, rawMessage->getInterface());
433-
}
434+
}
434435
};
435436
} else {
436437
DEBUG_SINRIC("[SinricPro.handleReceiveQueue()]: Signature is invalid! \r\n");
@@ -505,7 +506,7 @@ bool SinricProClass::isConnected() {
505506

506507
/**
507508
* @brief Set callback function for OTA (Over-The-Air) updates.
508-
*
509+
*
509510
* This method registers a callback function that will be called when an OTA update is available.
510511
* The callback should handle the process of downloading and applying the update.
511512
*
@@ -519,7 +520,7 @@ void SinricProClass::onOTAUpdate(OTAUpdateCallbackHandler cb) {
519520

520521
/**
521522
* @brief Set callback function for setting a module setting.
522-
*
523+
*
523524
* This method registers a callback function that will be called when a request to change
524525
* a module setting is received.
525526
* @return void
@@ -538,7 +539,7 @@ void SinricProClass::onSetSetting(SetSettingCallbackHandler cb) {
538539
* when the SinricPro system needs to report the device's health status.
539540
*
540541
* @param cb A function pointer of type ReportHealthCallbackHandler.
541-
* This callback should populate a String with health information and return a boolean
542+
* This callback should populate a String with health information and return a boolean
542543
* indicating success or failure of the health reporting process.
543544
* @return void
544545
* @see ReportHealthCallbackHandler for the definition of the callback function type.
@@ -660,17 +661,21 @@ void SinricProClass::setResponseMessage(String&& message) {
660661
}
661662

662663
/**
663-
* @brief Get the current timestamp
664+
* @brief
664665
*
665-
* @return unsigned long current timestamp (unix epoch time)
666+
* return unsigned long current timestamp(unix epoch time) * /
666667
*/
667668
unsigned long SinricProClass::getTimestamp() {
668669
return timestamp.getTimestamp();
669670
}
670671

672+
String SinricProClass::sign(const String& message) {
673+
return HMACbase64(message, appSecret);
674+
}
675+
671676
JsonDocument SinricProClass::prepareResponse(JsonDocument& requestMessage) {
672677
JsonDocument responseMessage;
673-
JsonObject header = responseMessage[FSTR_SINRICPRO_header].to<JsonObject>();
678+
JsonObject header = responseMessage[FSTR_SINRICPRO_header].to<JsonObject>();
674679
header[FSTR_SINRICPRO_payloadVersion] = 2;
675680
header[FSTR_SINRICPRO_signatureVersion] = 1;
676681

@@ -680,7 +685,7 @@ JsonDocument SinricProClass::prepareResponse(JsonDocument& requestMessage) {
680685
payload[FSTR_SINRICPRO_scope] = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_scope];
681686
payload[FSTR_SINRICPRO_createdAt] = 0;
682687
payload[FSTR_SINRICPRO_deviceId] = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_deviceId];
683-
if (requestMessage[FSTR_SINRICPRO_payload].containsKey(FSTR_SINRICPRO_instanceId)) payload[FSTR_SINRICPRO_instanceId] = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_instanceId];
688+
if (requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_instanceId].is<String>()) payload[FSTR_SINRICPRO_instanceId] = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_instanceId];
684689
payload[FSTR_SINRICPRO_message] = FSTR_SINRICPRO_OK;
685690
payload[FSTR_SINRICPRO_replyToken] = requestMessage[FSTR_SINRICPRO_payload][FSTR_SINRICPRO_replyToken];
686691
payload[FSTR_SINRICPRO_success] = false;
@@ -691,7 +696,7 @@ JsonDocument SinricProClass::prepareResponse(JsonDocument& requestMessage) {
691696

692697
JsonDocument SinricProClass::prepareEvent(String deviceId, const char* action, const char* cause) {
693698
JsonDocument eventMessage;
694-
JsonObject header = eventMessage[FSTR_SINRICPRO_header].to<JsonObject>();
699+
JsonObject header = eventMessage[FSTR_SINRICPRO_header].to<JsonObject>();
695700
header[FSTR_SINRICPRO_payloadVersion] = 2;
696701
header[FSTR_SINRICPRO_signatureVersion] = 1;
697702

src/SinricProCamera.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "Capabilities/SettingController.h"
1212
#include "Capabilities/PushNotification.h"
1313
#include "Capabilities/PowerStateController.h"
14+
#include "Capabilities/CameraController.h"
1415

1516
#include "SinricProNamespace.h"
1617
namespace SINRICPRO_NAMESPACE {
@@ -23,10 +24,12 @@ namespace SINRICPRO_NAMESPACE {
2324
class SinricProCamera : public SinricProDevice,
2425
public SettingController<SinricProCamera>,
2526
public PushNotification<SinricProCamera>,
26-
public PowerStateController<SinricProCamera> {
27+
public PowerStateController<SinricProCamera>,
28+
public CameraController<SinricProCamera> {
2729
friend class SettingController<SinricProCamera>;
2830
friend class PushNotification<SinricProCamera>;
2931
friend class PowerStateController<SinricProCamera>;
32+
friend class CameraController<SinricProCamera>;
3033
public:
3134
SinricProCamera(const String &deviceId) : SinricProDevice(deviceId, "CAMERA") {}
3235
};

0 commit comments

Comments
 (0)