11 #include <ESP8266WiFi.h>
12#elif defined(ESP32) || defined(ARDUINO_ARCH_RP2040)
16#include <ArduinoJson.h>
17#include <WebSocketsClient.h>
19#include "SinricProConfig.h"
20#include "SinricProDebug.h"
21#include "SinricProInterface.h"
22#include "SinricProNamespace.h"
23#include "SinricProQueue.h"
24namespace SINRICPRO_NAMESPACE {
26enum class ConnectionState {
32#if !defined(WEBSOCKETS_VERSION_INT) || (WEBSOCKETS_VERSION_INT < 2003005)
33#error "Wrong WebSockets Version! Minimum Version is 2.3.5!!!"
36using wsConnectedCallback = std::function<void(
void)>;
37using wsDisconnectedCallback = std::function<void(
void)>;
38using wsPongCallback = std::function<void(uint32_t)>;
40class WebsocketListener :
protected WebSocketsClient {
45 void begin(String server, String appKey, String deviceIds, SinricProQueue_t* receiveQueue);
48 void setRestoreDeviceStates(
bool flag);
50 void sendMessage(String& message);
52 void onConnected(wsConnectedCallback callback);
53 void onDisconnected(wsDisconnectedCallback callback);
54 void onPong(wsPongCallback callback);
56 using WebSocketsClient::disconnect;
57 using WebSocketsClient::isConnected;
61 bool restoreDeviceStates;
62 ConnectionState connectionState;
64 wsConnectedCallback _wsConnectedCb;
65 wsDisconnectedCallback _wsDisconnectedCb;
66 wsPongCallback _wsPongCb;
68 virtual void runCbEvent(WStype_t type, uint8_t* payload,
size_t length)
override;
70 void setExtraHeaders();
71 SinricProQueue_t* receiveQueue;
76WebsocketListener::WebsocketListener()
78 , restoreDeviceStates(false)
79 , connectionState(ConnectionState::disconnected)
80 , _wsConnectedCb(nullptr)
81 , _wsDisconnectedCb(nullptr)
82 , _wsPongCb(nullptr) {}
84WebsocketListener::~WebsocketListener() {
88void WebsocketListener::setExtraHeaders() {
90 const char* platform =
"ESP8266";
92 const char* platform =
"ESP32";
93#elif defined(ARDUINO_ARCH_RP2040)
94 const char* platform =
"RP2040";
97 String headers =
"appkey:" + appKey;
98 headers +=
"\r\ndeviceids:" + deviceIds;
99 headers +=
"\r\nrestoredevicestates:" + String(restoreDeviceStates ?
"true" :
"false");
100 headers +=
"\r\nip:" + WiFi.localIP().toString();
101 headers +=
"\r\nmac:" + WiFi.macAddress();
102 headers +=
"\r\nplatform:" + String(platform);
103 headers +=
"\r\nSDKVersion:" + String(SINRICPRO_VERSION);
105#ifdef FIRMWARE_VERSION
106 headers +=
"\r\nfirmwareVersion:" + String(FIRMWARE_VERSION);
109 DEBUG_SINRIC(
"[SinricPro:Websocket]: headers: \r\n%s\r\n", headers.c_str());
110 WebSocketsClient::setExtraHeaders(headers.c_str());
113void WebsocketListener::begin(String server, String appKey, String deviceIds, SinricProQueue_t* receiveQueue) {
116 connectionState = ConnectionState::connecting;
118 this->receiveQueue = receiveQueue;
119 this->appKey = appKey;
120 this->deviceIds = deviceIds;
123 DEBUG_SINRIC(
"[SinricPro:Websocket]: Connecting to WebSocket Server using SSL (%s)\r\n", server.c_str());
125 DEBUG_SINRIC(
"[SinricPro:Websocket]: Connecting to WebSocket Server (%s)\r\n", server.c_str());
128 if (isConnected()) stop();
130 enableHeartbeat(WEBSOCKET_PING_INTERVAL, WEBSOCKET_PING_TIMEOUT, WEBSOCKET_RETRY_COUNT);
132 WebSocketsClient::beginSSL(server.c_str(), SINRICPRO_SERVER_SSL_PORT,
"/");
134 WebSocketsClient::begin(server.c_str(), SINRICPRO_SERVER_PORT,
"/");
138void WebsocketListener::handle() {
142void WebsocketListener::stop() {
145 connectionState = ConnectionState::disconnected;
148void WebsocketListener::setRestoreDeviceStates(
bool flag) {
149 this->restoreDeviceStates = flag;
152void WebsocketListener::sendMessage(String& message) {
156void WebsocketListener::onConnected(wsConnectedCallback callback) {
157 _wsConnectedCb = callback;
160void WebsocketListener::onDisconnected(wsDisconnectedCallback callback) {
161 _wsDisconnectedCb = callback;
164void WebsocketListener::onPong(wsPongCallback callback) {
165 _wsPongCb = callback;
168void WebsocketListener::runCbEvent(WStype_t type, uint8_t* payload,
size_t length) {
172 case WStype_DISCONNECTED: {
173 DEBUG_SINRIC(
"[SinricPro:Websocket]: disconnected\r\n");
174 if (connectionState == ConnectionState::connected && _wsDisconnectedCb) _wsDisconnectedCb();
175 connectionState = ConnectionState::disconnected;
179 case WStype_CONNECTED:
180 DEBUG_SINRIC(
"[SinricPro:Websocket]: connected\r\n");
181 if (_wsConnectedCb) _wsConnectedCb();
182 if (restoreDeviceStates) {
183 restoreDeviceStates =
false;
186 connectionState = ConnectionState::connected;
190 SinricProMessage* request =
new SinricProMessage(IF_WEBSOCKET, (
char*)payload);
191 DEBUG_SINRIC(
"[SinricPro:Websocket]: receiving data\r\n");
192 receiveQueue->push(request);
197 if (_wsPongCb) _wsPongCb(millis() - _client.lastPing);